rlru 0.1.8

Rocket League replay uploader
Documentation

rlru

CI crates.io docs.rs license

Rust-first Rocket League replay uploader.

rlru uses strict TOML configuration, explicit local state paths, testable auth/upload boundaries, and a Dioxus client scaffold.

Crates

This repository is a Cargo workspace. The reusable pieces are published to crates.io as their own crates:

Crate Description crates.io docs.rs
rlru CLI + library for uploading Rocket League replays crates.io docs.rs
psynet Standalone client for Psyonix's PsyNet RPC backend (Rocket League online services) crates.io docs.rs

crates/psynet (README) is independent of the rest of rlru and can be depended on directly. The rlru-dioxus desktop client also lives in this workspace but is not published. All published crates currently share a single version number.

Library usage

rlru is a library as well as a CLI — the binary is a thin wrapper over the public API, so you can drive config, syncing, and uploads from your own Rust code.

[dependencies]
rlru = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use rlru::Config;
use rlru::paths::AppPaths;
use rlru::sync::SyncService;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let paths = AppPaths::discover()?;
    let config = Config::load_or_default(&paths.config_file())?;

    // Run one sync pass: discover new replays and push them to every
    // configured upload destination.
    let summary = SyncService::new(paths, config).run_once().await?;
    println!("uploaded {} replays", summary.uploaded);
    Ok(())
}

Key building blocks:

  • rlru::Config — strict TOML config, accounts, and upload destinations (Config::load, validate, helpers like UploadDestinationConfig::ballchasing()).
  • rlru::sync::SyncService — the sync engine (run_once, run_once_with_options, current_history).
  • rlru::upload — the upload destination abstraction.
  • rlru::psynet — the PsyNet client is re-exported as rlru::psynet, so rlru users don't need a separate dependency to talk to PsyNet directly.

Full API docs are on docs.rs/rlru and docs.rs/psynet.

Screenshots

Overview

History

Accounts

Upload Destinations

Development

direnv allow
just check
just run -- --help
just dioxus-desktop

Releases

Releases are driven entirely by the vX.Y.Z tag that matches the rlru Cargo package version. All published crates (rlru, psynet) share that single version number.

Fully automatic (recommended): bump the version in Cargo.toml, crates/psynet/Cargo.toml, and crates/rlru-dioxus/Cargo.toml and merge to main. The auto-tag-release workflow notices the new version and pushes the matching vX.Y.Z tag for you, which kicks off the release pipeline.

For the auto-created tag to trigger the downstream publish jobs, add a Personal Access Token (with contents: write) as the RELEASE_PAT repository secret — a tag pushed with the default GITHUB_TOKEN will not start new workflow runs. Without it, the tag is still created; just re-push it manually.

Manual: cut the tag yourself from a clean main checkout:

just release-tag

Either way, the tagged run:

  • uploads downloadable assets to the GitHub Releases page:
    • rlru-cli-linux-x86_64.tar.gz
    • rlru-cli-windows-x86_64.zip
    • rlru-dioxus-linux-x86_64.AppImage
  • publishes psynet then rlru to crates.io, when the CARGO_REGISTRY_TOKEN repository secret is configured (GitHub release assets are still created when that secret is absent).

Windows Builds From Linux

The dev shell includes the Fenix x86_64-pc-windows-gnu Rust target and the MinGW linker toolchain. Build Windows executables from Linux with:

just windows-cli release
just windows-dioxus release

The CLI executable lands under target/x86_64-pc-windows-gnu/release/rlru.exe. The Dioxus desktop executable lands under target/x86_64-pc-windows-gnu/release/rlru-dioxus.exe, with WebView2Loader.dll copied beside it.

Configuration

Print the effective default configuration:

rlru config defaults

Validate a configuration file:

rlru --config ~/.config/rlru/config.toml config validate

Tokens are stored separately from TOML config under the XDG config directory.

The default upload destinations include Rocky, Ballchasing, and Rocket Sense at https://rocket-sense.duckdns.org/api/v1. For Rocket Sense uploads, set ROCKET_SENSE_TOKEN to a Rocket Sense bearer token before running rlru sync, or configure a command that prints the token to stdout:

[storage.auth]
kind = "bearer_command"
command = ["pass", "show", "rocket-sense/token"]

Upload names

Replays are uploaded with a templated filename, which most destinations show as the replay's name. The default produces names like 2024-01-15.14.30 SaltySphinx Ranked Doubles Win. Customize it in [behavior]:

[behavior]
upload_name_template = "{YEAR}-{MONTH}-{DAY}.{HOUR}.{MIN} {PLAYER} {MODE} {WINLOSS}"

{PLAYER} and {WINLOSS} are from the synced account's perspective. Available placeholders:

Token Meaning
{YEAR} {MONTH} {DAY} Match date (local time, zero-padded)
{HOUR} {MIN} {SEC} Match time (local time, zero-padded)
{PLAYER} Synced account's in-match name (falls back to the account name)
{MODE} Playlist name (e.g. Ranked Doubles, Tournament)
{MAP} Map name (e.g. DFH Stadium)
{WINLOSS} Win / Loss / Draw for the synced account
{SCORE} Final score as team0-team1
{MATCH_ID} PsyNet match GUID

The rendered name is sanitized for use as a filename and gets a .replay extension automatically. Set upload_name_template = "" to keep the legacy match-id filename.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.