1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
= raidgrep(1)
:doctype: manpage
:man source: raidgrep
:man manual: raidgrep manpage
:toc:
:homepage: https://gitlab.com/dunj3/raidgrep
== NAME
raidgrep - A search tool for Guild Wars 2/arcdps log files.
== SYNOPSIS
*raidgrep* ['-OPTION' ['...']] ['--' ['-PREDICATE' ['...']]]
== DESCRIPTION
raidgrep is a CLI search tool to search through .evtc log files generated by
arcdps (a Guild Wars 2 addon).
raidgrep was inspired by other search tools - namely +ripgrep+ and +find+ - but
has support for reading and parsing the binary files produced by arcdps and
applying Guild Wars 2 specific filters.
== OPTIONS
The following options have to be given before any filters are given on the
command line:
*--debug*::
Print more debugging information to stderr.
*-l*, *--files-with-matches*::
Only show the name of matching files.
*--guilds*::
Load guild information from the API. +
+
Loading guild information requires network access and slows down the
program considerably, so this is disabled by default.
*--no-color*::
Disable colored output.
*--repl*::
Run the REPL.
*-V*, *--version*::
Prints version information.
*-d* 'path', *--dir* 'path'::
Path to the folder with logs [default: .]
*-c* 'file', *--check* 'file'::
Check the given log file only. +
+
If this option is given, the given file will be checked against the given
filter. This does not produce any output, will will set the exit code
accordingly (see section 'EXIT STATUS').
*-s* 'sorting', *--sort* 'sorting'::
Sort the output according to the given fields. Valid fields are 'boss',
'date', 'cm' and 'outcome'. Fields can be comma-separated, then later
fields are used to break ties. Fields can be prefixed by ~ to indicate
sorting in the opposite direction. +
+
Note that using this option will cause raidgrep to buffer all results until
the search has finished, which means that no output will happen until every
file has been searched. It can also lead to a higher memory consumption,
based on how many logs are matched. Therefore, it is advised that you do
not use this option unless needed. +
== PREDICATES
The following predicates can be used after the options. Note that they should
be preceeded by a +--+ on the command line, to signal the parser to switch from
parsing options to parsing predicates.
=== Predicate Combinators
'A' [*and*] 'B'::
Match the log only if both 'A' and 'B' are matching. The *and* is optional,
predicates written after each other are implicitely joined with *and*.
'A' *or* 'B'::
Match the log if 'A' or 'B' are matching.
*not* 'PREDICATE'::
Match the log only if the given predicate does not match.
*(* 'PREDICATE' *)*::
Parenthesis can be used to group predicates to enforce the correct operator
ordering.
=== Log Predicates
Those predicates can be used as-is in the filter:
*-success*::
Include logs that are successful.
*-wipe*::
Include logs that are failed.
*-outcome* 'OUTCOMES'::
Include logs with the given outcomes. Outcomes are 'success', 'wipe', or a
comma-separated combination thereof.
*-weekday* 'WEEKDAYS'::
Include logs made on the given weekdays. Weekdays are given either fully or
as a 3-letter-abbreviation and can be combined by commas.
*-before* 'DATE'::
Include logs made before the given date. Date can be either in
"year-month-day" or "year-month-day hour:minute:second" format.
*-after* 'DATE'::
Include logs made after the given date. See *-before* for valid date
formats.
*-log-before* 'DATE', *-log-after* 'DATE'::
Same as *-before* and *-after*, but does not use file name heuristics to
filter the date. +
+
This can fix wrong results in case you renamed files, but it comes at the
cost of worse runtime performance. You should always use *-before*/*-after*
when possible!
*-boss* 'BOSSES'::
Include logs from the given bosses. See below for a list of valid boss
names. Names can also be comma separated.
*-cm*::
Include logs that were done with the Challenge Mote enabled.
*-player* 'REGEX'::
Include logs in which at least one player's account or character name
matches the given regex. +
+
Note that you have to quote the regex if it contains spaces or other special characters.
*all(player:* 'PREDICATES' *)*::
Include logs in which all players match the given player predicates. See
below for a list of player predicates.
*any(player:* 'PREDICATES' *)*::
Include logs in which any player matches the given player predicates. See
below for a list of player predicates.
=== Comparative Predicates
Some predicates work by comparing a log value against a given constant (or
other computed value). Comparisons are done using the operators '<', '\<=', '=',
'>' and '>=' - in the list below, the placeholder '<>' will be used in place
of one of the comparison operators.
*-time* '<>' 'DATE'::
Include logs whose timestamp is in relation to the given date. This is a
generalized version of the *-before* and *-after* predicates and accepts
the same date formats.
*-duration* '<>' 'DURATION'::
Include logs whose duration is in relation to the given duration. The
duration is given as minutes and/or seconds: "42m", "42m 42s" or "42s".
*count(player)* '<>' 'COUNT'::
Include logs whose player count is in relation to the given count. This
counts all players in the log.
*count(player:* 'PREDICATES' *)* '<>' 'COUNT'::
Include logs whose player count is in relation to the given count, only
counting players that are matching the given player predicates. See below
for a list of player predicates.
=== Player Predicates
The following predicates have to be wrapped in either a *any(player: ...)*,
*all(player: ...)* or *count(player: ...)* construct to be accepted.
*-character* 'REGEX'::
Matches the player if the character name matches the given regular
expression.
*-account* 'REGEX'::
Matches the player if the account name matches the given regular
expression.
*-name* 'REGEX'::
Shorthand that matches if the character or the account name match the given
regular expression.
*-class* 'CLASSES'::
Match the player if they have one of the given classes. Note that a core
class won't match its elite specializations, so _Guardian_ won't match
_Dragonhunter_. +
+
Names can be comma separated, in which case the player must have any of the
listed classes.
=== Boss Names
Bosses can be referred to by their official name, although if that name
contains spaces it must be enclosed in quotes, and it's cumbersome to write.
Therefore, raidgrep also accepts a lot of shorthands that are established in
the community.
The following list is an inexhaustive list of all accepted boss names, with one
name per boss given:
* *Wing 1*: vg, gorseval, sabetha
* *Wing 2*: slothasor, matthias
* *Wing 3*: kc, xera
* *Wing 4*: cairn, mo, samarog, deimos
* *Wing 5*: desmina, dhuum
* *Wing 6*: ca, largos, qadim
* *Wing 7*: adina, sabir, qadimp
* *100 CM*: skorvald, artsariiv, arkk
* *99 CM*: mama, siax, ensolyss
* *Strike Missions*: icebrood, fraenir, kodans, boneskinner, whisper
=== Regular Expressions
raidgrep uses Rust's +regex+ library for regular expression support. A full
syntax reference can be found at https://docs.rs/regex/#syntax. A (very) short
primer is given here:
*foo*::
Match foo literally.
*foo|bar*::
Match either foo or bar.
*.*::
Match any character.
*^*::
Match the beginning of the string.
*$*::
Match the end of the string.
=== A Note About Quoting
raidgrep uses its own parser to split and parse the given predicates. However,
when calling raidgrep from the command line, the shell also applies some
splitting. raidgrep tries to reconstruct the given predicates as good as
possible, but it does not always work.
This means that sometimes, predicates as described here may not work correctly
when used in the CLI argument. To circumvent this, there are multiple options:
* Use the raidgrep REPL, which is not subject to your shell's splitting.
* Pass the filter as a single big argument, which is usually achieved by
enclosing it in quotes and escaping any quotes in the filter.
Most use cases should work without much adaption. If there is a case that looks
like it should work but doesn't, feel free to report it as a bug (see below).
== REPL
If given the *--repl* option, raidgrep will not start searching for logs and
instead enter a read-eval-print-loop. You can give it a predicate, it will
print the results and ask for the next predicate.
Any options given in this mode will apply to the whole REPL session. For
example, if started with *-l*, all REPL evaluations will only print the file
names of the matching files.
== EXIT STATUS
raidgrep will exit with status 0 (success) if at least one matching log was
found, with status 1 if no logs were found and status 2 if there was an error.
If used with the REPL mode, raidgrep will always exit with status 0.
== EXAMPLES
The following are examples of predicates as they might be entered in the REPL.
They can also be used on the command line, but proper escaping might have to be
applied (depending on your shell):
+-success -player Godric+::
Find any logs that were successful and had a player called "Godric" in
them.
+-wipe (-player Godric or -player Emma)+::
Find any logs that were unsuccesful and had either a player called "Godric"
or a player called "Emma" in them.
+-after 2020-01-01 any(player: -character Xenia)+::
Find any logs after the 1st of January 2020 where a player had a character
name matching "Xenia".
The following examples are raidgrep invocations that show how predicates can be
supplied as arguments to raidgrep:
`raidgrep -- -success -player Godric`::
Same as above. Special quoting is not necessary, as raidgrep can figure out
what the user meant.
`raidgrep -- -player "Godric Gobbledygook"`::
Find any logs with a player called "Godric Gobbledygook". Raidgrep can
figure out how the quotes were meant to be, even though the shell stripped
them away.
`raidgrep -- 'all(player: -character "o{2}")'`::
In this example, the whole command line is wrapped in single quotes, to
prevent the shell from splitting it apart. This should work for most
predicates.
== FILES
* '$XDG_CACHE_HOME/raidgrep': Temporary data.
* '$XDG_CONFIG_HOME/raidgrep/history': REPL history.
Note that 'XDG_CACHE_HOME' defaults to '\~/.cache' if unset, and
'XDG_CONFIG_HOME' defaults to '~/.config'.
== BUGS
Bugs and other issues are tracked in the Gitlab repository at
https://gitlab.com/dunj3/raidgrep/-/issues.
If you want to report a bug, you can either
* Open an issue in the aforementioned issue tracker
* Write an email to mailto:raidgrep@kingdread.de[]
* Contact me through Guild Wars 2: +Dunje.4863+
When reporting a bug, please include as much information as you can beforehand
- that includes the version of raidgrep that you are using, your operating
system and (if possible) the log file itself that raidgrep fails on.
== COPYRIGHT
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
== RESOURCES
* Source repository: https://gitlab.com/dunj3/raidgrep/
* Binary releases: https://kingdread.de/raidgrep/
* arcdps addon for Guild Wars 2: https://www.deltaconnected.com/arcdps/
== AUTHOR
*raidgrep* was written by Daniel Schadt.
|