# steamroom
Utilities for interacting with Steam's API
## History
This project is a **cleanroom** reimplementation of [DepotDownloader](https://github.com/steamre/depotdownloader).
I originally used an LLM to translate DepotDownloader to Rust, and put all of that [DepotDownloader-rs](https://github.com/landaire/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
```bash
cargo install --path crates/steamroom-cli
```
## Quick Start
```bash
# 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.
```bash
# 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.
```bash
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.
```bash
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
```
### `files`
List files in a depot manifest.
```bash
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
```
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
```
### `workshop`
Download Steam Workshop items.
```bash
steamroom workshop --app 440 --item 123456789 -o workshop/
```
## Authentication
steamroom supports multiple authentication methods:
| 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` |
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:
```bash
DD_COMPAT=1 steamroom -app 480 -depot 481 -dir output/ -validate
```
## Features
- TCP and WebSocket transports
- Pipelined chunk downloads with resume support
- 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](https://github.com/SteamRE/DepotDownloader) v3.4.0 (C#/.NET) using [hyperfine](https://github.com/sharkdp/hyperfine). Anonymous login, Windows 11, same network.
\\\\\\\ to: mpptwwzu 280b1323 "perf: better-optimized Adler32 implementation" (rebased revision)
-| Download Spacewar (1.8 MB) | 1.80s ± 0.12s | 4.03s ± 0.16s | **2.2x** |
-| Download CS2 content (2.5 GB) | 22.0s ± 0.5s | 33.1s ± 2.2s | **1.5x** |
+| 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.
<details>
<summary>Reproduce benchmarks</summary>
```bash
# 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:
```bash
nix develop
./bench/run.sh /path/to/scratch
```
</details>
See [FEATURES.md](FEATURES.md) for a full feature comparison.
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT License ([LICENSE-MIT](LICENSE-MIT))
at your option.