steam_client/services/
familysharing.rs1use steam_enums::EMsg;
7use steamid::SteamID;
8
9use crate::{error::SteamError, SteamClient};
10
11#[derive(Debug, Clone)]
13pub struct AuthorizedBorrower {
14 pub steamid: SteamID,
16 pub is_pending: bool,
18 pub is_canceled: bool,
20 pub time_created: u32,
22}
23
24#[derive(Debug, Clone)]
26pub struct AuthorizedDevice {
27 pub device_token: u64,
29 pub device_name: String,
31 pub is_pending: bool,
33 pub is_canceled: bool,
35 pub is_limited: bool,
37 pub last_time_used: Option<u32>,
39 pub last_borrower: Option<SteamID>,
41 pub last_app_played: Option<u32>,
43}
44
45impl SteamClient {
46 pub async fn add_authorized_borrowers(&mut self, borrowers: Vec<SteamID>) -> Result<(), SteamError> {
51 if !self.is_logged_in() {
52 return Err(SteamError::NotLoggedOn);
53 }
54
55 let msg = steam_protos::CDeviceAuthAddAuthorizedBorrowersRequest {
56 steamid: self.steam_id.as_ref().map(|s| s.steam_id64()),
57 steamid_borrower: borrowers.iter().map(|s| s.steam_id64()).collect(),
58 };
59
60 let _: steam_protos::CDeviceAuthAddAuthorizedBorrowersResponse = self.send_unified_request_and_wait("DeviceAuth.AddAuthorizedBorrowers#1", &msg).await?;
61
62 Ok(())
63 }
64
65 pub async fn remove_authorized_borrowers(&mut self, borrowers: Vec<SteamID>) -> Result<(), SteamError> {
70 if !self.is_logged_in() {
71 return Err(SteamError::NotLoggedOn);
72 }
73
74 let msg = steam_protos::CDeviceAuthRemoveAuthorizedBorrowersRequest {
75 steamid: self.steam_id.as_ref().map(|s| s.steam_id64()),
76 steamid_borrower: borrowers.iter().map(|s| s.steam_id64()).collect(),
77 };
78
79 let _: steam_protos::CDeviceAuthRemoveAuthorizedBorrowersResponse = self.send_unified_request_and_wait("DeviceAuth.RemoveAuthorizedBorrowers#1", &msg).await?;
80
81 Ok(())
82 }
83
84 pub async fn get_authorized_borrowers(&mut self, include_canceled: bool, include_pending: bool) -> Result<Vec<AuthorizedBorrower>, SteamError> {
90 if !self.is_logged_in() {
91 return Err(SteamError::NotLoggedOn);
92 }
93
94 let msg = steam_protos::CDeviceAuthGetAuthorizedBorrowersRequest {
95 steamid: self.steam_id.as_ref().map(|s| s.steam_id64()),
96 include_canceled: Some(include_canceled),
97 include_pending: Some(include_pending),
98 };
99
100 let response: steam_protos::CDeviceAuthGetAuthorizedBorrowersResponse = self.send_unified_request_and_wait("DeviceAuth.GetAuthorizedBorrowers#1", &msg).await?;
101
102 let borrowers = response
103 .borrowers
104 .into_iter()
105 .map(|b| AuthorizedBorrower {
106 steamid: SteamID::from(b.steamid.unwrap_or(0)),
107 is_pending: b.is_pending.unwrap_or(false),
108 is_canceled: b.is_canceled.unwrap_or(false),
109 time_created: b.time_created.unwrap_or(0),
110 })
111 .collect();
112
113 Ok(borrowers)
114 }
115
116 pub async fn get_authorized_sharing_devices(&mut self, include_canceled: bool) -> Result<Vec<AuthorizedDevice>, SteamError> {
121 if !self.is_logged_in() {
122 return Err(SteamError::NotLoggedOn);
123 }
124
125 let msg = steam_protos::CDeviceAuthGetOwnAuthorizedDevicesRequest { steamid: self.steam_id.as_ref().map(|s| s.steam_id64()), include_canceled: Some(include_canceled) };
126
127 let response: steam_protos::CDeviceAuthGetOwnAuthorizedDevicesResponse = self.send_unified_request_and_wait("DeviceAuth.GetOwnAuthorizedDevices#1", &msg).await?;
128
129 let devices = response
130 .devices
131 .into_iter()
132 .map(|d| AuthorizedDevice {
133 device_token: d.auth_device_token.unwrap_or(0),
134 device_name: d.device_name.unwrap_or_default(),
135 is_pending: d.is_pending.unwrap_or(false),
136 is_canceled: d.is_canceled.unwrap_or(false),
137 is_limited: d.is_limited.unwrap_or(false),
138 last_time_used: d.last_time_used,
139 last_borrower: d.last_borrower_id.map(SteamID::from),
140 last_app_played: d.last_app_played,
141 })
142 .collect();
143
144 Ok(devices)
145 }
146
147 pub async fn authorize_local_sharing_device(&mut self, device_name: &str) -> Result<u64, SteamError> {
155 if !self.is_logged_in() {
156 return Err(SteamError::NotLoggedOn);
157 }
158
159 let msg = steam_protos::CMsgClientAuthorizeLocalDeviceRequest {
160 device_description: Some(device_name.to_string()),
161 owner_account_id: Some(self.steam_id.as_ref().map(|s| s.account_id).unwrap_or(0)),
162 local_device_token: None,
163 };
164
165 let response: steam_protos::CMsgClientAuthorizeLocalDevice = self.send_request_and_wait(EMsg::ClientAuthorizeLocalDeviceRequest, &msg).await?;
166
167 if let Some(result) = response.eresult {
168 if result != 1 {
169 return Err(SteamError::SteamResult(steam_enums::EResult::from_i32(result).unwrap_or(steam_enums::EResult::Fail)));
170 }
171 }
172
173 Ok(response.authed_device_token.unwrap_or(0))
174 }
175
176 pub async fn deauthorize_sharing_device(&mut self, device_token: u64) -> Result<(), SteamError> {
181 if !self.is_logged_in() {
182 return Err(SteamError::NotLoggedOn);
183 }
184
185 let msg = steam_protos::CMsgClientDeauthorizeDeviceRequest {
186 deauthorization_account_id: Some(self.steam_id.as_ref().map(|s| s.account_id).unwrap_or(0)),
187 deauthorization_device_token: Some(device_token),
188 };
189
190 let response: steam_protos::CMsgClientDeauthorizeDevice = self.send_request_and_wait(EMsg::ClientDeauthorizeDeviceRequest, &msg).await?;
191
192 if let Some(result) = response.eresult {
193 if result != 1 {
194 return Err(SteamError::SteamResult(steam_enums::EResult::from_i32(result).unwrap_or(steam_enums::EResult::Fail)));
195 }
196 }
197
198 Ok(())
199 }
200
201 pub async fn use_sharing_authorization(&mut self, owner_steam_id: SteamID, device_token: u64) -> Result<(), SteamError> {
207 if !self.is_logged_in() {
208 return Err(SteamError::NotLoggedOn);
209 }
210
211 let msg = steam_protos::CMsgClientUseLocalDeviceAuthorizations {
212 authorization_account_id: vec![owner_steam_id.account_id],
213 device_tokens: vec![steam_protos::c_msg_client_use_local_device_authorizations::DeviceToken { owner_account_id: Some(owner_steam_id.account_id), token_id: Some(device_token) }],
214 };
215
216 self.send_message(EMsg::ClientUseLocalDeviceAuthorizations, &msg).await
217 }
218
219 pub async fn deactivate_sharing_authorization(&mut self) -> Result<(), SteamError> {
221 if !self.is_logged_in() {
222 return Err(SteamError::NotLoggedOn);
223 }
224
225 let msg = steam_protos::CMsgClientUseLocalDeviceAuthorizations { authorization_account_id: vec![], device_tokens: vec![] };
226
227 self.send_message(EMsg::ClientUseLocalDeviceAuthorizations, &msg).await
228 }
229}