use crate::{error::SteamError, SteamClient};
#[derive(Debug, Clone)]
pub struct SteamGuardDetails {
pub is_steamguard_enabled: bool,
pub is_email_auth_enabled: bool,
pub is_mobile_auth_enabled: bool,
pub timestamp_steamguard_enabled: Option<u64>,
pub timestamp_two_factor_enabled: Option<u64>,
pub machine_sessions: Vec<MachineSession>,
}
#[derive(Debug, Clone)]
pub struct MachineSession {
pub machine_name: String,
pub first_login: u64,
pub last_login: u64,
pub last_ip: Option<String>,
}
#[derive(Debug, Clone)]
pub struct PrivacySettings {
pub privacy_state: u32,
pub privacy_state_inventory: u32,
pub privacy_state_gifts: u32,
pub privacy_state_owned_games: u32,
pub privacy_state_playtime: u32,
pub privacy_state_friends_list: u32,
}
#[derive(Debug, Clone)]
pub struct AccountLimitations {
pub is_limited: bool,
pub is_community_banned: bool,
pub is_locked: bool,
pub can_invite_friends: bool,
}
#[derive(Debug, Clone)]
pub struct EmailInfo {
pub address: String,
pub validated: bool,
}
#[derive(Debug, Clone)]
pub struct VacBans {
pub num_bans: u32,
pub app_ids: Vec<u32>,
}
#[derive(Debug, Clone)]
pub struct WalletInfo {
pub has_wallet: bool,
pub balance: i32,
pub currency: i32,
}
impl SteamClient {
pub async fn request_validation_email(&mut self) -> Result<(), SteamError> {
if !self.is_logged_in() {
return Err(SteamError::NotLoggedOn);
}
let request = steam_protos::CMsgClientRequestValidationEmail {};
self.send_message(steam_enums::EMsg::ClientRequestValidationMail, &request).await
}
pub async fn get_steam_guard_details(&mut self) -> Result<SteamGuardDetails, SteamError> {
if !self.is_logged_in() {
return Err(SteamError::NotLoggedOn);
}
let request = steam_protos::CCredentialsGetSteamGuardDetailsRequest::default();
self.send_service_method("Credentials.GetSteamGuardDetails#1", &request).await?;
Ok(SteamGuardDetails {
is_steamguard_enabled: false,
is_email_auth_enabled: false,
is_mobile_auth_enabled: false,
timestamp_steamguard_enabled: None,
timestamp_two_factor_enabled: None,
machine_sessions: Vec::new(),
})
}
pub async fn get_privacy_settings(&mut self) -> Result<PrivacySettings, SteamError> {
if !self.is_logged_in() {
return Err(SteamError::NotLoggedOn);
}
let request = steam_protos::CPlayerGetPrivacySettingsRequest {};
let response: steam_protos::CPlayerGetPrivacySettingsResponse = self.send_unified_request_and_wait("Player.GetPrivacySettings#1", &request).await?;
if let Some(settings) = response.privacy_settings {
Ok(PrivacySettings {
privacy_state: settings.privacy_state.unwrap_or(0) as u32,
privacy_state_inventory: settings.privacy_state_inventory.unwrap_or(0) as u32,
privacy_state_gifts: settings.privacy_state_gifts.unwrap_or(0) as u32,
privacy_state_owned_games: settings.privacy_state_ownedgames.unwrap_or(0) as u32,
privacy_state_playtime: settings.privacy_state_playtime.unwrap_or(0) as u32,
privacy_state_friends_list: settings.privacy_state_friendslist.unwrap_or(0) as u32,
})
} else {
Err(SteamError::Other("No privacy settings returned".into()))
}
}
pub fn get_account_limitations(&self) -> Result<AccountLimitations, SteamError> {
if let Some(limitations) = self.account.read().limitations.clone() {
Ok(AccountLimitations {
is_limited: limitations.limited,
is_community_banned: limitations.community_banned,
is_locked: limitations.locked,
can_invite_friends: limitations.can_invite_friends,
})
} else {
Err(SteamError::Other("Account limitations not available yet".into()))
}
}
pub fn get_vac_bans(&self) -> Result<VacBans, SteamError> {
if let Some(vac) = self.account.read().vac.clone() {
Ok(VacBans { num_bans: vac.num_bans, app_ids: vac.appids.clone() })
} else {
Err(SteamError::Other("VAC status not available yet".into()))
}
}
pub async fn get_credential_change_times(&mut self) -> Result<CredentialChangeTimes, SteamError> {
if !self.is_logged_in() {
return Err(SteamError::NotLoggedOn);
}
let request = steam_protos::CCredentialsLastCredentialChangeTimeRequest { user_changes_only: Some(true) };
let response: steam_protos::CCredentialsLastCredentialChangeTimeResponse = self.send_unified_request_and_wait("Credentials.GetCredentialChangeTimeDetails#1", &request).await?;
Ok(CredentialChangeTimes {
password_last_changed: response.timestamp_last_password_change.map(|t| t as u64),
email_last_changed: response.timestamp_last_email_change.map(|t| t as u64),
})
}
pub async fn get_auth_secret(&mut self) -> Result<(i32, Vec<u8>), SteamError> {
if !self.is_logged_in() {
return Err(SteamError::NotLoggedOn);
}
let request = steam_protos::CCredentialsGetAccountAuthSecretRequest::default();
let response: steam_protos::CCredentialsGetAccountAuthSecretResponse = self.send_unified_request_and_wait("Credentials.GetAccountAuthSecret#1", &request).await?;
Ok((response.secret_id.unwrap_or(0), response.secret.unwrap_or_default()))
}
}
#[derive(Debug, Clone)]
pub struct CredentialChangeTimes {
pub password_last_changed: Option<u64>,
pub email_last_changed: Option<u64>,
}
#[derive(Debug, Clone)]
pub struct AccountInfo {
pub name: String,
pub country: String,
pub authed_machines: i32,
pub flags: u32,
pub facebook_id: Option<u64>,
pub facebook_name: Option<String>,
pub phone_verified: bool,
pub two_factor_state: u32,
}
impl From<&steam_protos::CMsgClientAccountInfo> for AccountInfo {
fn from(msg: &steam_protos::CMsgClientAccountInfo) -> Self {
Self {
name: msg.persona_name.clone().unwrap_or_default(),
country: msg.ip_country.clone().unwrap_or_default(),
authed_machines: msg.count_authed_computers.unwrap_or(0),
flags: msg.account_flags.unwrap_or(0),
facebook_id: msg.facebook_id,
facebook_name: msg.facebook_name.clone(),
phone_verified: msg.is_phone_verified.unwrap_or(false),
two_factor_state: msg.two_factor_state.unwrap_or(0),
}
}
}