diff --git a/src/auth.rs b/src/auth.rs index 53fbf9c..fadd0fe 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,3 +1,4 @@ +use std::thread::AccessError; use reqwest::blocking::*; use log::*; use serde::Deserialize; @@ -136,65 +137,6 @@ impl DeviceCredentials { _ => { error!("Failed to get device_id!"); }, } } - pub fn get_device_auth_and_secret_from(&mut self, http_client: &Client, access_token: &str, account_id: &str) { - - if access_token.is_empty() || account_id.is_empty() { - error!("Device access token cannot be empty!"); - return; - } - - let mut url : String = String::from("https://account-public-service-prod.ol.epicgames.com/account/api/public/account/"); - url.push_str(account_id); - url.push_str("/deviceAuth"); - - /* - let it : String = String::new; - it.starts_with("one thing"); - // Just discovered String.starts_with() KEKW - */ - - #[derive(Debug, Deserialize)] - struct CreatedObject { - location: String, - ipAddress: String, - dateTime: String, - } - - #[derive(Debug, Deserialize)] - struct ResponseStruct { - deviceId: String, - accountId: String, - secret: String, - userAgent: String, - created: CreatedObject, - } - - let mut bearer_header = String::from("Bearer "); - bearer_header.push_str(access_token); - - let response = Client::post(&http_client, url) - .header("Authorization", bearer_header) - .send(); - - match response { - Ok(response_data) => { - match response_data.json::().ok() { - Some(response_json) => { - self.device_id = response_json.deviceId; - self.secret = response_json.secret; - } - None => { - error!("Failed to parse device_id!"); - }, - } - }, - _ => { error!("Failed to get device_id!"); }, - } - } - - pub fn get_exchange_code() -> String { - todo!(); - } } #[derive(Debug)] @@ -210,8 +152,7 @@ impl TemporaryCredentials { exchange_code : String::new(), } } - - pub fn get_access_token(&mut self, http_client: &Client, device_credentials: &DeviceCredentials) { + pub fn get_access_token_from_device_auth(&mut self, http_client: &Client, device_credentials: &DeviceCredentials) /*Android*/ { #[derive(Debug, Deserialize)] struct ResponseStruct { @@ -262,7 +203,7 @@ impl TemporaryCredentials { request_body = request_body.trim().to_string(); } - let url : &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token"; + let url : &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token"; let response = Client::post(&http_client, url) .body(request_body) @@ -285,7 +226,57 @@ impl TemporaryCredentials { _ => { error!("Failed to get access token!"); }, } } - pub fn get_exchange_code(&mut self, http_client: &Client) { + pub fn get_access_token_from_exchange_code(&mut self, http_client: &Client, temporary_credentials: &TemporaryCredentials) /*Generic*/ { + #[derive(Debug, Deserialize)] + struct ResponseStruct { + access_token: String, + /*expires_in: u16, + expires_at: String, + token_type: String, + refresh_token: String, + refresh_expires: u16, + refresh_expires_at: String, + account_id: String, + client_id: String, + internal_client: bool, + client_service: String, + displayName: String, + app: String, + in_app_id: String, + acr: String, + auth_time: String*/ + } + + let mut request_body = String::new(); + request_body.push_str("grant_type=exchange_code&exchange_code=".trim()); + request_body.push_str(temporary_credentials.exchange_code.as_str().trim()); + + let url : &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/token"; + + let response = http_client.post(url) + .body(request_body) + .header("Content-Type", "application/x-www-form-urlencoded") + .header("Authorization", + "Basic MzRhMDJjZjhmNDQxNGUyOWIxNTkyMTg3NmRhMzZmOWE6ZGFhZmJjY2M3Mzc3NDUwMzlkZmZlNTNkOTRmYzc2Y2Y=") + .send(); + + match response { + Ok(response_data) => { + match response_data.json::().ok() { + Some(response) => { + self.access_token = response.access_token; + }, + None => { + error!("Failed to parse access_token!"); + } + } + }, + _ => { error!("Failed to get access token!"); }, + } + + + } + pub fn get_exchange_code(&mut self, http_client: &Client, client_id: &str) { #[derive(Debug,Deserialize)] struct ResponseStruct { @@ -296,16 +287,19 @@ impl TemporaryCredentials { let mut bearer_header = String::from("Bearer "); bearer_header.push_str(self.access_token.as_str()); - + + let mut query_content : String = String::from("?consumingClientId=").trim().to_string(); + query_content.push_str(client_id.trim()); + let url: &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/exchange"; let response = Client::get(&http_client, url) + //.query(query_content.as_str()) + .query(&[("consumingClientId",client_id.trim())]) .header("Authorization", bearer_header.as_str()) .send(); - - match response { - Ok(response_data) => { + Ok(response_data) => { match response_data.json::().ok() { Some(response_json) => { self.exchange_code = response_json.code; @@ -317,9 +311,5 @@ impl TemporaryCredentials { }, _ => { error!("Failed to get Exchange code!"); }, } - - } - pub fn get_exchange_code_from(&mut self, http_client: &Client, access_token: &str) {todo!();} - } diff --git a/src/main.rs b/src/main.rs index deeb09d..40260e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,25 +62,28 @@ fn main() { // Getting temporal info to create persistent login info let mut auth_code: String = "".to_string(); let _ = std::io::stdin().read_line(&mut auth_code).unwrap(); - + let mut persistent_credentials: DeviceCredentials = DeviceCredentials::new(); - { - persistent_credentials.get_access_token_and_account_id(&http_client, &auth_code); - persistent_credentials.get_device_auth_and_secret(&http_client); - dbg!(&persistent_credentials); - } + persistent_credentials.get_access_token_and_account_id(&http_client, &auth_code); + persistent_credentials.get_device_auth_and_secret(&http_client); + dbg!(&persistent_credentials); - let mut login_credentials: TemporaryCredentials = TemporaryCredentials::new(); - { - login_credentials.get_access_token(&http_client, &persistent_credentials); - login_credentials.get_exchange_code(&http_client); - dbg!(&login_credentials); - } + /* Android temporary credentials */ + let mut android_credentials: TemporaryCredentials = TemporaryCredentials::new(); + android_credentials.get_access_token_from_device_auth(&http_client, &persistent_credentials); + android_credentials.get_exchange_code(&http_client, "34a02cf8f4414e29b15921876da36f9a"); + dbg!(&android_credentials); + + /* Generic temporary credentials */ + let mut generic_credentials : TemporaryCredentials = TemporaryCredentials::new(); + generic_credentials.get_access_token_from_exchange_code(&http_client, &android_credentials); + generic_credentials.get_exchange_code(&http_client, "ec684b8c687f479fadea3cb2ad83f5c6"); + dbg!(&generic_credentials); /* Game Launching*/ let mut auth_password_argument = String::from("-AUTH_PASSWORD="); - auth_password_argument.push_str(login_credentials.exchange_code.as_str()); + auth_password_argument.push_str(generic_credentials.exchange_code.as_str()); let mut uid_argument = String::from("-epicuserid="); uid_argument.push_str(persistent_credentials.account_id.as_str()); @@ -90,16 +93,35 @@ fn main() { .arg("start") .arg("/d") .arg("D:\\Games\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64") // Path to the directory - .arg("FortniteLauncher.exe") // The executable + .arg("FortniteLauncher.exe") // The executable .arg("-AUTH_LOGIN=unused") .arg(&auth_password_argument) .arg("-AUTH_TYPE=exchangecode") .arg("-epicapp=Fortnite") .arg("-epicenv=Prod") .arg("-EpicPortal") + .arg("-steamimportavailable") .arg(&uid_argument) + .arg("-epicsandboxid=fn") .spawn(); + /* + "D:\Games\Epic Games\Fortnite\FortniteGame\Binaries\Win64/FortniteClient-Win64-Shipping_EAC_EOS.exe" + -obfuscationid=N8Kw52kUZsQq50886Eit-gzJOBar1g + -AUTH_LOGIN=unused -AUTH_PASSWORD=91ec3f72c2d94c8598082d58fc007a02 + -AUTH_TYPE=exchangecode + -epicapp=Fortnite + -epicenv=Prod + -EpicPortal + -epicusername=Generic_Boi69 + -epicuserid=bff1ee7d635140ed945f69a0595526b2 + -epiclocale=en + -epicsandboxid=fn + -named_pipe=bff1ee7d635140ed945f69a0595526b2\Fortnite + -fromfl=eaceos + -caldera=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50X2lkIjoiYmZmMWVlN2Q2MzUxNDBlZDk0NWY2OWEwNTk1NTI2YjIiLCJnZW5lcmF0ZWQiOjE3MzQ1NDMwNDYsImNhbGRlcmFHdWlkIjoiOTUyZmU2OTktZjJjMy00YjZlLTk2NzctOWRlMDMyOTcyZjkxIiwiYWNQcm92aWRlciI6IkVhc3lBbnRpQ2hlYXRFT1MiLCJub3RlcyI6IiIsInByZSI6dHJ1ZSwicGFlIjpmYWxzZSwiZmFsbGJhY2siOmZhbHNlfQ.SaiRyK-FFbzCI3TVM8RRFS0UyCu5VUsTlIMeNKPZHYcKUORdE7fZJlo0DC4zoZsPfmLNEzZxCLb_sJVPiy-m7A + */ + match command { Ok(mut child) => { // Optionally, you can wait for the process to complete