Changed access_token and exchange_code fetching methods and started game using a generic token to enable playing games.

This commit is contained in:
Marta Borgia Leiva 2024-12-18 23:56:57 +01:00
parent ed702813b0
commit f2ceb4c621
2 changed files with 97 additions and 85 deletions

View file

@ -1,3 +1,4 @@
use std::thread::AccessError;
use reqwest::blocking::*; use reqwest::blocking::*;
use log::*; use log::*;
use serde::Deserialize; use serde::Deserialize;
@ -136,65 +137,6 @@ impl DeviceCredentials {
_ => { error!("Failed to get device_id!"); }, _ => { 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::<ResponseStruct>().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)] #[derive(Debug)]
@ -210,8 +152,7 @@ impl TemporaryCredentials {
exchange_code : String::new(), exchange_code : String::new(),
} }
} }
pub fn get_access_token_from_device_auth(&mut self, http_client: &Client, device_credentials: &DeviceCredentials) /*Android*/ {
pub fn get_access_token(&mut self, http_client: &Client, device_credentials: &DeviceCredentials) {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct ResponseStruct { struct ResponseStruct {
@ -262,7 +203,7 @@ impl TemporaryCredentials {
request_body = request_body.trim().to_string(); 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) let response = Client::post(&http_client, url)
.body(request_body) .body(request_body)
@ -285,7 +226,57 @@ impl TemporaryCredentials {
_ => { error!("Failed to get access token!"); }, _ => { 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::<ResponseStruct>().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)] #[derive(Debug,Deserialize)]
struct ResponseStruct { struct ResponseStruct {
@ -296,16 +287,19 @@ impl TemporaryCredentials {
let mut bearer_header = String::from("Bearer "); let mut bearer_header = String::from("Bearer ");
bearer_header.push_str(self.access_token.as_str()); 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 url: &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/exchange";
let response = Client::get(&http_client, url) let response = Client::get(&http_client, url)
//.query(query_content.as_str())
.query(&[("consumingClientId",client_id.trim())])
.header("Authorization", bearer_header.as_str()) .header("Authorization", bearer_header.as_str())
.send(); .send();
match response { match response {
Ok(response_data) => { Ok(response_data) => {
match response_data.json::<ResponseStruct>().ok() { match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => { Some(response_json) => {
self.exchange_code = response_json.code; self.exchange_code = response_json.code;
@ -317,9 +311,5 @@ impl TemporaryCredentials {
}, },
_ => { error!("Failed to get Exchange code!"); }, _ => { error!("Failed to get Exchange code!"); },
} }
} }
pub fn get_exchange_code_from(&mut self, http_client: &Client, access_token: &str) {todo!();}
} }

View file

@ -62,25 +62,28 @@ fn main() {
// Getting temporal info to create persistent login info // Getting temporal info to create persistent login info
let mut auth_code: String = "".to_string(); let mut auth_code: String = "".to_string();
let _ = std::io::stdin().read_line(&mut auth_code).unwrap(); let _ = std::io::stdin().read_line(&mut auth_code).unwrap();
let mut persistent_credentials: DeviceCredentials = DeviceCredentials::new(); let mut persistent_credentials: DeviceCredentials = DeviceCredentials::new();
{ persistent_credentials.get_access_token_and_account_id(&http_client, &auth_code);
persistent_credentials.get_access_token_and_account_id(&http_client, &auth_code); persistent_credentials.get_device_auth_and_secret(&http_client);
persistent_credentials.get_device_auth_and_secret(&http_client); dbg!(&persistent_credentials);
dbg!(&persistent_credentials);
}
let mut login_credentials: TemporaryCredentials = TemporaryCredentials::new(); /* Android temporary credentials */
{ let mut android_credentials: TemporaryCredentials = TemporaryCredentials::new();
login_credentials.get_access_token(&http_client, &persistent_credentials); android_credentials.get_access_token_from_device_auth(&http_client, &persistent_credentials);
login_credentials.get_exchange_code(&http_client); android_credentials.get_exchange_code(&http_client, "34a02cf8f4414e29b15921876da36f9a");
dbg!(&login_credentials); 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*/ /* Game Launching*/
let mut auth_password_argument = String::from("-AUTH_PASSWORD="); 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="); let mut uid_argument = String::from("-epicuserid=");
uid_argument.push_str(persistent_credentials.account_id.as_str()); uid_argument.push_str(persistent_credentials.account_id.as_str());
@ -90,16 +93,35 @@ fn main() {
.arg("start") .arg("start")
.arg("/d") .arg("/d")
.arg("D:\\Games\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64") // Path to the directory .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_LOGIN=unused")
.arg(&auth_password_argument) .arg(&auth_password_argument)
.arg("-AUTH_TYPE=exchangecode") .arg("-AUTH_TYPE=exchangecode")
.arg("-epicapp=Fortnite") .arg("-epicapp=Fortnite")
.arg("-epicenv=Prod") .arg("-epicenv=Prod")
.arg("-EpicPortal") .arg("-EpicPortal")
.arg("-steamimportavailable")
.arg(&uid_argument) .arg(&uid_argument)
.arg("-epicsandboxid=fn")
.spawn(); .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 { match command {
Ok(mut child) => { Ok(mut child) => {
// Optionally, you can wait for the process to complete // Optionally, you can wait for the process to complete