• BETA 1.0.0-beta.6
  • SOLO WINDOWS

vStats Desktop: companion per Windows in sola lettura

Un'app per Windows che riconosce l'inizio della partita e mostra il contesto della tua lobby (rank, chi gioca in gruppo con chi e un punteggio di fair-play) man mano che arrivano i risultati.

Ruolo
progettata e realizzata (core Rust, interfaccia, strumenti di rilascio, endpoint backend)
Tipo
prodotto proprio, app Windows
Stato
beta, 1.0.0-beta.6
Piattaforma
Windows

Problema

Gli utenti di vStats volevano informazioni sulla partita mentre era in corso: il rank di ogni giocatore, chi era in gruppo e un punteggio di fair-play. Questo richiede di leggere i dati locali del client di gioco in sola lettura, tenere la sessione dell'utente lontana dal codice web e aggiornare l'app in modo sicuro, perché quasi nessuno reinstalla un'app a mano.

Risultato

In beta pubblica per Windows (1.0.0-beta.6), con aggiornamenti firmati distribuiti dal server di vStats e test sul backend per i flussi di rilascio e di lobby.

Approfondimento tecnico (in inglese)

What I built

I built a Tauri 2 app with a Rust core and a React 19 + TypeScript interface. The Rust side owns the account, the connection to the local game client and every server call, and the interface only draws what it is sent. Every 3 seconds a background loop works out whether the player is in the menus, agent select or a live game, then builds the lobby roster. Results arrive from the vStats backend as a stream, one line per player, so one slow lookup never holds up the rest. Sign-in works by email or by Riot Sign-On through a protected deep link, and the session token lives in Windows Credential Manager. The app also has a tray icon, autostart, a "Match found" notification and signed automatic updates.

Highlights

  1. ARCHITECTURE

    A thin interface over a Rust core.

    21 commands connect the interface to the core, and changes in sign-in, lobby and update state are pushed to the interface as events.

  2. DETECTION

    A resilient background loop.

    Rank lookups run in parallel. A failed lookup waits before it is retried, a failed scan backs off, and party numbering stays stable when the roster reorders.

  3. READ-ONLY

    Scoped trust for the local client.

    The connection to the local game client pins Riot's root certificate. Only if that fails with a certificate error does it accept the client's self-signed certificate, and only for that one local port. It never calls anything that changes game state.

  4. STREAMING

    Results that fill in as they arrive.

    The backend answers in NDJSON, and a line buffer in Rust hands each player's row to the interface the moment it is complete.

  5. UPDATES

    Signed updates, end to end.

    The app checks shortly after launch and then every 6 hours. The server compares versions with pre-release tags handled correctly (tested: beta.10 is newer than beta.9) and accepts only releases with an HTTPS installer and a well-formed signature, which the app verifies before installing.

  6. HARDENING

    A locked-down shell.

    A strict content security policy, a navigation guard, an allow-list for external links, a single-instance lock, rustls in place of native TLS, and an optimised release build packaged as a per-user NSIS installer.

How it works

vStats Desktop streaming flowThe Rust core reads the local game client read-only, sends the lobby roster to the vStats backend, receives one result line per player as each lookup finishes, and passes each row to the interface, which fills in. The list below describes each step.Local game client(read-only)Rust corevStats backendInterface1match phase2roster3one line per player…4vStats Desktop streaming flowThe Rust core reads the local game client read-only, sends the lobby roster to the vStats backend, receives one result line per player as each lookup finishes, and passes each row to the interface, which fills in. The list below describes each step.Local gameclientRust corevStatsbackendInterface(read-only)1match phase2roster3…4
  1. The Rust core reads the local game client, read-only, to detect the match phase.
  2. When a match is found, it sends the roster to the vStats backend.
  3. The backend streams back one line per player as each lookup finishes.
  4. The core passes each row to the interface, which fills in the roster.

Stack

  • Tauri 2
  • Rust (tokio, reqwest + rustls, serde, keyring)
  • React 19
  • TypeScript
  • Vite
  • Vitest
  • Node.js/Express endpoints
  • NDJSON streaming
  • NSIS
  • signed updates

By the numbers

  • ~4,000lines of Rust in 21 files
  • 21interface-to-core commands
  • 25 + 18Rust tests + interface tests
  • 6 hupdate check interval

Outcome

In public beta for Windows (1.0.0-beta.6), with signed updates delivered from the vStats server, and backend tests covering the release and lobby flows.

Ti serve qualcosa di simile? Chiedi un preventivo gratuito.

Preventivo gratuito

VALORANT e Riot Games sono marchi di Riot Games, Inc. Questo progetto non è affiliato a Riot Games né approvato da Riot Games.

VALORANT and Riot Games are trademarks of Riot Games, Inc. This project is not affiliated with or endorsed by Riot Games.