/spyparsey

🕵️ A tool for parsing and querying a collection of SpyParty replays

Primary LanguageRust

SpyParsey

A tool for parsing and querying a collection of SpyParty replays.

Installation

  • Download the latest version
  • Put it anywhere you like
  • Run it from the command line
  • It'll pick up your replays automatically (if they are stored in the default path), otherwise you can specify folders with the --path option.

Usage

Below is the current help text for the tool:

USAGE:
    spyparsey.exe [FLAGS] [OPTIONS]

FLAGS:
        --count
            Outputs a count of the matched replays

        --countdown
            Filters games that end with the 10 second mission win countdown

        --csv
            Outputs matched replays in a verbose CSV format

    -h, --help
            Prints help information

        --show-paths
            Outputs a list of the paths of matched replays

        --sniperwin
            Filters games that end in a sniper win

        --spywin
            Filters games that end in a spy win

    -V, --version
            Prints version information

    -v
            Sets the verbosity level for logging


OPTIONS:
        --completed-missions <MISSIONS>...
            Filters games that contain specific missions, ANY of which were completed

        --completed-missions-all <MISSIONS>...
            Filters games that contain specific missions, ALL of which were completed

        --maps <MAPS>...
            Filters based maps

        --modes <MODES>...
            Filters games that are a specific game mode

        --pair <NAMES>...
            Filters based on a pair of players who have played together

        --paths <PATHS>...
            Sets the list of paths to look for replays (can be directories or single replays)

        --players <NAMES>...
            Filters based on players' names (either spy or sniper). This uses OR matching, so if you use multiple player
            names it finds games with ANY of the players, not ALL of the players. If you want find the games where two
            players have played together, use the --pair option.
        --results <RESULTS>...
            Filters based on the result of the game [possible values: missionswin, spyshot, civilianshot, timeout,
            unfinished]
        --snipers <NAMES>...
            Filters based on snipers' names

        --spies <NAMES>...
            Filters based on spies' names

All Possible Filter Values

--maps
  • aquarium
  • balcony
  • ballroom
  • courtyard
  • "crowded pub" or crowdedpub
  • "double modern" or doublemodern
  • gallery
  • "high rise", high-rise or highrise
  • modern
  • moderne
  • "old balcony" or oldbalcony
  • "old ballroom" or oldballroom
  • "old courtyard 1", oldcourtyard1 or cy1
  • "old courtyard 2", oldcourtyard2 or cy2
  • "old gallery" or oldgallery
  • "old veranda" or oldveranda
  • panopticon or panop
  • pub
  • redwoods
  • teien
  • terrace
  • veranda
  • unknown
--completed-missions / --completed-missions-all
  • "bug ambassador", bugambassador or bug
  • "contact double agent", contactdoubleagent, contactda, contact or bb
  • "fingerprint ambassador", fingerprintambassador, fingerprint or fp
  • "inspect statues", inspectstatues or inspect
  • "purloin guest list", purloinguestlist or purloin
  • "seduce target", seducetarget or seduce
  • "swap statue", swapstatue or swap
  • "transfer microfilm", transfermicrofilm, transfermf or mf
--modes
  • any or a
  • pick or p
  • known or k
  • "any 7 of 8", "any 7/8", a7/8
  • "pick 7 of 8", "pick 7/8", p7/8
  • "known 4 of 4", "known 4/4", "known 4", k4
--result
  • missionswin
  • spyshot
  • civilianshot
  • timeout
  • unfinished

Examples

  • Find all replays from a particular player:

    spyparsey --player plastikqs

  • Find all replays where a player shot a civilian on Ballroom or High-Rise:

    spyparsey --sniper plastikqs --map ballroom highrise --result civilianshot

  • Find all replays where that were an "Any x/y" mode, where both bug and contact DA were completed:

    spyparsey --mode any --completed-missions-all bug bb

  • Find out how many times you beat Dowsey on Balcony with bug, BB and seduce:

    spyparsey --spy plastikqs --sniper dowsey --map balcony --result missionswin --completed-missions-all bug bb seduce

Output

There are currently 3 modes of output. Explicit outputs are the following:

  • --count

    Just show the number of replays that matched the filters.

  • --show-paths

    Show the absolute paths of the replays that matched the filters. This can be piped into another command, maybe used to sort replays into various folders.

  • --csv

    Outputs all the matched replays in a rather verbose CSV format. It includes almost every piece of data you can get from the header. I'm sure someone can think of clever ways to use this...

However, the default mode if you specify neither of the above is to output a few stats. What exactly is output depends on the filters (i.e. if you filter based on map, you won't get the "Maps Played" section). Below is an example of all the stats possible:

Total Replays:
    2625
Player Stats:
    plastikqs: 1461W 1149L (55.7%)
Maps Played:
    Courtyard: 592 (22.6%)
    Ballroom: 389 (14.8%)
    Pub: 301 (11.5%)
    Library: 270 (10.3%)
    High-Rise: 251 (9.6%)
    Moderne: 188 (7.2%)
    Gallery: 141 (5.4%)
    Balcony: 134 (5.1%)
    Terrace: 132 (5.0%)
    Veranda: 119 (4.5%)
    Aquarium: 72 (2.7%)
    Teien: 32 (1.2%)
    Panopticon: 2 (0.1%)
    Old Balcony: 2 (0.1%)
Missions Completed:
    Contact Double Agent: 1369 (53.4%)
    Purloin Guest List: 1023 (45.1%)
    Inspect Statues: 1016 (47.0%)
    Bug Ambassador: 1000 (39.7%)
    Seduce Target: 774 (30.2%)
    Swap Statue: 692 (31.9%)
    Transfer Microfilm: 285 (23.4%)
    Fingerprint Ambassador: 227 (10.2%)
Completed Mission Sets:
    Bug, BB, Inspect, Seduce: 63 (8.0%)
    BB, Inspect, Seduce, Purloin: 44 (5.6%)
    BB, Swap, Inspect, Purloin: 33 (4.2%)
    BB, Swap, Inspect, Seduce: 33 (4.2%)
    Bug, BB: 30 (3.8%)
    Bug, BB, Swap, Inspect: 29 (3.7%)
    Bug, BB, Swap, Seduce: 28 (3.5%)
    BB, Inspect, Seduce, Fingerprint: 27 (3.4%)
    Bug, BB, Seduce: 26 (3.3%)
    Bug, BB, Inspect, Purloin: 25 (3.2%)
Clock:
    Average Duration: 2m25s
    Clock Usage: 73.1%
Modes Played:
    Any: 2499 (95.2%)
    Known: 122 (4.6%)
    Pick: 4 (0.2%)
Results:
    Spy Shot: 1443 (55.0%)
    Civilian Shot: 553 (21.1%)
    Missions Win: 518 (19.7%)
    Spy Timeout: 96 (3.7%)
    Unfinished: 15 (0.6%)

These stats become quite useful/interesting when paired with specific filters. For example, you could find out which missions I tend to complete when I win as a spy on High-Rise a3/5:

$ spyparsey --spy plastikqs --map highrise --mode a3/5 --result missionswin
Total Replays:
    28
Player Stats:
    plastikqs: 28W 0L (100.0%)
Missions Completed:
    Contact Double Agent: 19 (79.2%)
    Seduce Target: 14 (63.6%)
    Purloin Guest List: 12 (66.7%)
    Transfer Microfilm: 11 (68.8%)
    Bug Ambassador: 10 (52.6%)
    Inspect Statues: 9 (50.0%)
    Swap Statue: 7 (53.8%)
    Fingerprint Ambassador: 4 (40.0%)
Completed Mission Sets:
    Bug, BB, Transfer MF: 3 (11.5%)
    BB, Seduce, Purloin: 3 (11.5%)
    Bug, BB, Purloin: 2 (7.7%)
    Swap, Inspect, Purloin: 2 (7.7%)
    BB, Inspect, Seduce: 2 (7.7%)
    Transfer MF, Seduce, Purloin: 2 (7.7%)
    BB, Transfer MF, Seduce: 2 (7.7%)
    BB, Transfer MF, Purloin: 1 (3.8%)
    BB, Inspect, Fingerprint: 1 (3.8%)
    Bug, Swap, Inspect: 1 (3.8%)
Clock:
    Average Duration: 2m39s
    Clock Usage: 90.4%

Seems like I enjoy going for those hard tells!

Notes

  • Most of the filter options have aliases to their singular counterpart, but behave the same way i.e. --spy works the same as --spies.
  • I haven't optimised or done much performance-wise, but it's basically limited by disk read. When running over 20,000 replays it takes about 20 seconds to run the first time (regardless of filters) and then subsequent runs take less than a second or two (again, regardless of filters changing).
  • SpyParty replays and folders have really long names, especially when players start creating their own organisation. If the entire path of a replay exceeds 260 characters, neither SpyParty nor spyparsey will be able to read these and will be missing in the output. You can use the -vv flag to see warnings about files that could not be read.

Contribution

Any fixes or new features are welcomed! The ideal way to provide these would be via a pull request from your own forks.

Contributing is made a little trickier since this project has been split into two parts:

  • this repo, which is basically the UI for the parser, providing filtering and output
  • the library repo, which actually contains the code for parsing individual replays

Often, changes to both of these repos may be required for a single feature. An example of this would be adding support for a new venue. Since this may be the most common feature that might require a contribution, below is an example of the changes to each repo that are necessary: