Skip to content

Repository files navigation

DeadAPI

DeadAPI is a work-in-progress API for Valve's game Deadlock.

Development

This repository is a Rust workspace. The workspace contains deployable services and shared components.

Start PostgreSQL Without Compose

Use this command when you run a service directly on the host:

docker run --detach \
  --name deadapi-postgres \
  --restart unless-stopped \
  --env POSTGRES_USER=deadapi \
  --env POSTGRES_PASSWORD=deadapi_dev \
  --env POSTGRES_DB=deadapi \
  --publish 127.0.0.1:5432:5432 \
  --volume deadapi-postgres-data:/var/lib/postgresql/data \
  docker.io/library/postgres:17-alpine

Run the Local Pipeline with Docker Compose

The development stack contains PostgreSQL, the ingest API, the metadata worker, the artifact downloader, and the stats parser.

Create the local configuration files before you start the stack:

install -m 600 configs/development/ingest.example.json configs/development/ingest.json
install -m 600 configs/development/metadata.example.json configs/development/metadata.json
install -m 600 configs/development/demo-downloader.example.json configs/development/demo-downloader.json
install -m 600 configs/development/stats-parser.json configs/development/stats-parser.json

Open configs/development/metadata.json. Set account_name to your Steam login name. Replace the refresh-token placeholder with your Steam refresh token.

Open configs/development/demo-downloader.json. Replace the R2 endpoint, access key, and secret key placeholders with credentials scoped to the configured metadata and demo buckets.

Open configs/development/stats-parser.json. Configure the same metadata bucket with read access.

Run these commands from the repository root:

docker compose up --build --detach
docker compose ps
docker compose logs --follow ingest metadata demo-downloader stats-parser

You can use the same Compose file with Podman. Replace docker compose with podman compose. Install a Compose provider before you use Podman Compose. The Z mount option applies a private SELinux label to each bind mount on Fedora.

PostgreSQL runs each file in migrations/ when it creates the data volume. PostgreSQL does not run these files again on an existing volume.

If you change a migration, delete the development volume. Then, start the stack again:

docker compose down --volumes
docker compose up --build --detach

Use a valid Deadlock match ID to add a job:

curl --request POST http://127.0.0.1:8000/ingest \
  --header 'content-type: application/json' \
  --data '{"match_id": 123456789}'

curl http://127.0.0.1:8000/ingest/123456789

Open http://127.0.0.1:8000 to view the Apalis Board dashboard. The dashboard displays queue metrics, worker status, and task states.

Open http://127.0.0.1:8000/docs to use the OpenAPI interface.

After artifact download, the stats parser downloads the compressed metadata, decodes Valve's match and player analytics, persists them in PostgreSQL, and marks the ingestion job completed. Both workers process up to four matches concurrently by default. Set worker.max_concurrent_downloads in its configuration to change that limit. Set worker.download_demo to false to persist only the metadata artifact; metadata-only jobs still advance to stats parsing. Set worker.max_concurrent_jobs in the stats parser configuration to change its concurrency.

The pipeline uses three typed Apalis queues: metadata resolution, artifact download, and stats parsing. Apalis owns task claiming, worker heartbeats, retry backoff, concurrency, graceful shutdown, and recovery of orphaned tasks. You can monitor each queue in the Apalis Board dashboard. The ingestion_jobs table remains the public pipeline state read by the ingest status endpoint. Each successful stage updates that row and enqueues the next typed task in one PostgreSQL transaction.

Use this command to stop the stack and keep the PostgreSQL data:

docker compose down

Configure a Service for Direct Use

Create a configuration file for each service that you want to run:

cp configs/ingest.example.json configs/ingest.json
cp configs/metadata.example.json configs/metadata.json
cp configs/demo-downloader.example.json configs/demo-downloader.json
cp configs/stats-parser.json configs/stats-parser.json

Replace all placeholder credentials. Each binary reads its configuration file only during startup.

Start a Service Directly

Run the applicable command from the repository root:

cargo run --package ingest
cargo run --package ingest -- --config /absolute/path/to/ingest.json
cargo run --package metadata
cargo run --package demo-downloader
cargo run --package stats-parser

The --config option is not necessary when you use configs/<service>.json.

The ingest service listens on 127.0.0.1:8000. The root path / serves the Apalis Board dashboard. The /docs route serves the OpenAPI interface. The /api/v1 route exposes the Apalis Board REST API.

The metadata service opens one Game Coordinator connection for each configured Steam account. PostgreSQL stores account leases and the request cooldown. The default request cooldown is 1,728 seconds. Multiple metadata replicas can use the same mounted configuration file.

Create a Steam Refresh Token

Use a trusted computer to create the token. Run these commands:

cd scripts/steam-refresh-token
bun install
bun run get-token

Use Steam Guard to scan the displayed QR code. Approve the login in Steam Guard. The script saves the token in steam-refresh-token.txt. File permissions give access only to the file owner.

Set account_name to the Steam login name that the script displays. Copy the token to the applicable steam.accounts[].access_token field. Delete steam-refresh-token.txt after the metadata worker connects. The Steam account must have Deadlock in its library.

Use a Configuration File in a Container

Mount the configuration file as a read-only file at /etc/deadapi/config.json:

docker run --mount type=bind,src=/secure/ingest.json,dst=/etc/deadapi/config.json,readonly \
  <ingest-image> --config /etc/deadapi/config.json

Do not add a production configuration file to the container image. Give read permission only to the runtime service user. Use the secret-file mount that your deployment platform supplies.

Run SQLx Checks and Tests

DATABASE_URL=postgres://deadapi:deadapi_dev@127.0.0.1:5432/deadapi \
cargo test --workspace

Cargo reads each package name from the name field in the applicable Cargo.toml file.

About

an api for valves unreleased moba deadlock

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages