steamroom-cli 0.2.0

Command-line tool for downloading Steam depot content
Documentation

steamroom

Utilities for interacting with Steam's API

History

This project is a cleanroom reimplementation of DepotDownloader.

I originally used an LLM to translate DepotDownloader to Rust, and put all of that DepotDownloader-rs. However, I realized that GPL licensing is a pain in the ass for Rust projects because of static linking, and decided to do the following:

  1. Generate docs for the conversion library
  2. Delete the source code from the docs
  3. Copy that + the file tree and old ddl binary to a new repo
  4. Instruct a new LLM session how to reverse engineer steam (using Binary Ninja MCP + Steam libs loaded)
  5. Told it to reimplement it to the API spec
  6. ???
  7. 4 Hours later, we're GPL-free

Any major improvements done to this library should, in spirit of collaboration, be shared back to the SteamRE/DepotDownloader project in the spirit of advancing everyone's capabilities.

Not to air my personal grievances with GPL in this README, but DepotDownloader has been a godsend for many projects and I do believe in the spirit of upstreaming changes you make to libraries you use. I don't like the idea of GPL infecting things which statically link against the library, however. And that is the only reason why this library exists as a cleanroom reimplementation.

Install

cargo install --path crates/steamroom-cli

Quick Start

# Download Spacewar (free game, no login required)
steamroom download --app 480 --depot 481 -o spacewar/

# Download with authentication (prompts for password + 2FA)
steamroom --username myaccount download --app 440 -o tf2/

# QR code login (scan with Steam mobile app)
steamroom --username myaccount --qr download --app 440 -o tf2/

# Use a saved token (auto-detected from ~/.depotdownloader/tokens.json)
steamroom --username myaccount download --app 440 -o tf2/

Commands

download

Download depot content to a local directory.

# Basic download
steamroom download --app 480 --depot 481 -o output/

# Specific manifest version
steamroom download --app 480 --depot 481 --manifest 3183503801510301321 -o output/

# Download a specific branch
steamroom download --app 480 --depot 481 --branch previous -o output/

# Filter files by regex
steamroom download --app 480 --depot 481 --file-regex '\.dll$' -o output/

# Filter files by list
steamroom download --app 480 --depot 481 --filelist files.txt -o output/

# Verify existing files (skip up-to-date, re-download changed)
steamroom download --app 480 --depot 481 --verify -o output/

# Control parallelism
steamroom download --app 480 --depot 481 --max-downloads 16 -o output/

info

Show app metadata, depots with sizes, and branches.

steamroom info --app 730

# Filter depots by OS
steamroom info --app 730 --os linux

# Include redistributable depots
steamroom info --app 730 --show-all

# JSON output for scripting
steamroom info --app 730 --format json

Example output:

App ID:  730
Name:    Counter-Strike 2
Type:    Game

Depots:
  ID        CONFIGURATION          SIZE          DL.
  2347770   64-bit            50.44 GiB    42.93 GiB
  2347771   Windows            7.07 GiB     5.05 GiB
  2347772   macOS              9.06 KiB     1.66 KiB
  2347773   Linux, 64-bit      6.62 GiB     4.71 GiB
  2347774   64-bit          1023.01 MiB   843.02 MiB
  ...

Branches:
  NAME               DESCRIPTION                           BUILD      TIME BUILT    TIME UPDATED
  animgraph_2_beta   Animgraph 2 Beta                      22720547   2d ago        2d ago
  1.41.4.1           1.41.4.1                              22627914   9d ago        9d ago
  public                                                   22627914   9d ago        9d ago
  1.41.4.0           1.41.4.0                              22370414   26d ago       26d ago
  ...

manifests

List depot manifest IDs for a branch.

steamroom manifests --app 480
steamroom manifests --app 480 --branch previous
steamroom manifests --app 480 --format json

Example output:

Manifests for branch 'public':

  depot 229006   -> --
  depot 481      -> 3183503801510301321

save-manifest

Download and save a depot manifest without downloading content. Saves the raw CDN response (.zip), decompressed manifest (.manifest), and depot key (depot.json).

# Save latest manifest
steamroom save-manifest --app 552990 --depot 552993 -o manifests/

# Save a specific manifest version
steamroom save-manifest --app 552990 --depot 552993 --manifest 6791242355553147175 -o manifests/

files

List files in a depot manifest.

steamroom files --app 480 --depot 481

# Plain output (one filename per line, for piping)
steamroom files --app 480 --depot 481 --format plain

# Raw byte sizes
steamroom files --app 480 --depot 481 --bytes

# JSON output
steamroom files --app 480 --depot 481 --format json

# Read from a local manifest file (key auto-detected from depot.json)
steamroom files --manifest-file manifests/.depotdownloader/manifests/552993_123.manifest --depot 552993

# Explicit depot key (hex)
steamroom files --manifest-file path/to/552993_123.manifest --depot-key a4ac589393a2c8679c1f99b2e6fcee10554c030a0a6bf69bd4e22a13da7aab55

# Show raw encrypted filenames (no key needed)
steamroom files --manifest-file path/to/552993_123.manifest --raw

Example output:

Depot:    481
Manifest: 3183503801510301321
Created:  2019-02-06 21:51:33 UTC
Size:     1.82 MiB
Files:    8

FILENAME                          SIZE   CHUNKS
DejaVuSans.txt                2.76 KiB        1
sdkencryptedappticket.dll   558.28 KiB        1
DejaVuSans.ttf              703.96 KiB        1
installscript.vdf                514 B        1
steam_api.dll               219.78 KiB        1
SteamworksExample.exe       374.00 KiB        1
controller.vdf                1.53 KiB        1
D3D9VRDistort.cso                576 B        1

diff

Compare two manifests and show added, removed, and changed files.

steamroom diff --app 480 --depot 481 --from 3183503801510301321 --to 8271816315493618441
steamroom diff --app 480 --depot 481 --from 3183503801510301321 --to 8271816315493618441 --format json

packages

Query Steam package (sub) details by ID.

steamroom packages 17906
steamroom packages 17906 29197 --format json

workshop

Download Steam Workshop items.

steamroom workshop --app 440 --item 123456789 -o workshop/

local-info

Show locally cached depot keys and beta branches from Steam's config.vdf.

steamroom local-info
steamroom local-info --format json
steamroom local-info --users
steamroom local-info --user myaccount

Daemon mode

steamroom can run as a background daemon that holds an authenticated Steam session and services CLI invocations over a local socket. Reusing the session avoids the per-command CM discovery, handshake, and logon round trip, so repeated commands run faster.

The daemon authenticates either at launch, when daemon start is given auth flags, or lazily on its first job, when started without them (using an auto-detected saved token, or anonymous). It serves one account for its lifetime; to switch accounts, stop and restart it. It reconnects if the CM connection drops.

# Start a daemon. With auth flags it logs in now; without them it logs in
# lazily on the first job.
steamroom --username myaccount daemon start
steamroom daemon start

# Route commands through the daemon. If none is running, --use-daemon
# starts one in lazy auth mode first.
steamroom --use-daemon info --app 730
steamroom --use-daemon download --app 480 --depot 481 -o spacewar/

# Jump the queue.
steamroom --use-daemon --priority info --app 730

# Submit without waiting, then reattach by job id.
steamroom --use-daemon --detach download --app 480 --depot 481
steamroom daemon attach <job-id>

# Observe.
steamroom daemon status              # ratatui dashboard
steamroom daemon status --text       # one-shot text snapshot
steamroom daemon status --format json
steamroom daemon info                # pid, socket, and stop command

# Stop.
steamroom daemon stop
steamroom daemon stop --force        # cancel the active job too

Job history persists across restarts, so daemon status and daemon attach can see jobs from earlier daemon runs.

Auth flags (--username, --password, --qr, --use-steam-token, --remember-password, --device-name) and --capture are ignored, with a warning, under --use-daemon; the daemon serves the account it authenticated as. Set them on daemon start instead.

Authentication

steamroom supports multiple authentication methods:

Method Flag Notes
Anonymous (none) Works for free games
Password --username X --password Y Prompts if password omitted
Password + 2FA --username X Prompts for guard code
QR code --username X --qr Scan with Steam mobile app
Saved token --username X Auto-loads from ~/.depotdownloader/tokens.json
Steam token --use-steam-token Reuses cached token from local Steam installation

Tokens are saved automatically after successful login and reused on subsequent runs.

Legacy Compatibility

Set DD_COMPAT=1 to use single-dash arguments compatible with the original DepotDownloader:

DD_COMPAT=1 steamroom -app 480 -depot 481 -dir output/ -validate

Features

  • TCP and WebSocket CM transports
  • HTTP/2 multiplexed chunk downloads with CDN server pool rotation
  • Chunk-level delta downloads (only fetches changed chunks via Adler-32 comparison)
  • Local Steam credential reuse (--use-steam-token) on Windows, Linux, and macOS
  • Local depot key and beta hash reuse from Steam's config.vdf (--local-keys)
  • Manifest diff, package queries, manifest-only download, local manifest reading
  • Non-atomic write mode for direct chunk-to-file writes
  • Serde deserializer for Valve KeyValue format
  • C/C++ FFI bindings via Diplomat, Python bindings via nanobind
  • Proto extraction tool for steamclient64.dll
  • Fuzz targets for binary parsers

Architecture

steamroom              — Core Steam protocol: crypto, connection, transport, depot, messages
steamroom-client       — High-level: download orchestration, manifest cache, credentials
steamroom-cli          — CLI binary (produces `steamroom` executable)
steamroom-ffi          — C/C++ FFI bindings via Diplomat
steamroom-proto-extract — Tool to extract protobuf definitions from Steam binaries

Benchmarks

Compared against DepotDownloader v3.4.0 (C#/.NET) using hyperfine. Anonymous login, Windows 11, same network.

Benchmark steamroom DepotDownloader Speedup
App info query (480) 0.67s ± 0.06s 2.85s ± 1.02s 4.3x
File listing (480/481) 1.67s ± 0.06s 3.34s ± 1.01s 2.0x
Download Spacewar (1.8 MB) 1.23s ± 0.14s 4.04s ± 0.16s 3.3x
Download CS2 content (2.5 GB) 23.6s 32.1s 1.4x

Both tools are network-bound for large downloads. Results will vary by network and hardware. Run bench/run.sh to reproduce on your own setup.

# Build release
cargo build --release -p steamroom-cli

# Run with hyperfine (clean state each run to prevent resume skew)
hyperfine --min-runs 3 -N \
  --prepare "rm -rf /tmp/sr /tmp/dd" \
  -n steamroom "steamroom download --app 480 --depot 481 -o /tmp/sr" \
  -n DepotDownloader "DepotDownloader -app 480 -depot 481 -dir /tmp/dd"

Or use the included benchmark script with nix:

nix develop
./bench/run.sh /path/to/scratch

See FEATURES.md for a full feature comparison.

License

Licensed under either of:

at your option.