steam-client-rs 0.1.0

Steam client for Rust - Individual and Anonymous user account types
Documentation
//! Steam-User Example - BasicBot
//!
//! Simply logs into Steam using a refresh token, goes online on friends, and
//! launches TF2.
//!
//! # Usage
//! ```bash
//! REFRESH_TOKEN="your_refresh_token" cargo run --example basic_bot
//! ```

use std::time::Duration;

use steam_client::{AppsEvent, AuthEvent, ConnectionEvent, EPersonaState, FriendsEvent, LogOnDetails, SteamClient, SteamError, SteamEvent, SystemEvent};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init();

    // Get refresh token from environment variable
    let refresh_token = std::env::var("REFRESH_TOKEN").expect("Please set REFRESH_TOKEN environment variable");

    // Create Steam client
    let mut client = SteamClient::new(Default::default());

    println!("🚀 Connecting to Steam...");

    // Log on with refresh token
    let response = client.log_on(LogOnDetails { refresh_token: Some(refresh_token), ..Default::default() }).await?;

    println!("✅ Logged into Steam as {}", response.steam_id.steam3());

    // Set persona to Online with a custom name
    client.set_persona(EPersonaState::Online, Some("Playing with Rust 🦀".to_string())).await?;
    println!("👤 Set persona to Online");

    // Play Team Fortress 2 (AppID 440)
    client.games_played(vec![440]).await?;
    println!("🎮 Now playing Team Fortress 2");

    // Main event loop
    println!("\n📡 Listening for events (Ctrl+C to stop)...\n");

    loop {
        match client.poll_event_timeout(Duration::from_secs(30)).await {
            Ok(Some(event)) => {
                match event {
                    // Friends list received
                    SteamEvent::Friends(FriendsEvent::FriendsList { friends, .. }) => {
                        println!("👥 Friends list received: {} friends", friends.len());
                    }

                    // Persona state update
                    SteamEvent::Friends(FriendsEvent::PersonaState(persona)) => {
                        println!("👤 {} is now {:?}", persona.player_name, persona.persona_state);
                    }

                    // Licenses (owned games)
                    SteamEvent::Apps(AppsEvent::LicenseList { licenses }) => {
                        println!("📦 Account owns {} license(s)", licenses.len());
                    }

                    // Refresh token (save this!)
                    SteamEvent::Auth(AuthEvent::RefreshToken { token, account_name }) => {
                        println!("💾 New refresh token for {}: {}...", account_name, &token[..20.min(token.len())]);
                    }

                    // Disconnection
                    SteamEvent::Connection(ConnectionEvent::Disconnected { reason, will_reconnect }) => {
                        if will_reconnect {
                            println!("🔄 Disconnected ({:?}), will reconnect...", reason);
                        } else {
                            println!("❌ Disconnected permanently: {:?}", reason);
                            break;
                        }
                    }

                    // Logged off
                    SteamEvent::Auth(AuthEvent::LoggedOff { result }) => {
                        println!("👋 Logged off: {:?}", result);
                        break;
                    }

                    // Debug messages
                    SteamEvent::System(SystemEvent::Debug(msg)) => {
                        tracing::debug!("Debug: {}", msg);
                    }

                    // Errors
                    SteamEvent::System(SystemEvent::Error(msg)) => {
                        println!("❌ Error: {}", msg);
                    }

                    // Other events
                    _ => {
                        tracing::debug!("Unhandled event: {:?}", event);
                    }
                }
            }
            Ok(None) => {
                // Timeout - no event received
                println!("⏰ Heartbeat: still connected...");
            }
            Err(SteamError::NotConnected) => {
                println!("❌ Connection lost");
                break;
            }
            Err(e) => {
                println!("❌ Error: {:?}", e);
                break;
            }
        }
    }

    // Clean up
    client.log_off().await?;
    println!("👋 Goodbye!");

    Ok(())
}