Managed to launch game correctly

This commit is contained in:
Marta Borgia Leiva 2024-12-18 02:44:51 +01:00
parent 1e35e945b4
commit 6f003af531
2 changed files with 224 additions and 19 deletions

View file

@ -10,24 +10,27 @@ const OAUTH_TOKEN : (&str, &str)= (
#[derive(Debug)] #[derive(Debug)]
pub struct DeviceCredentials { pub struct DeviceCredentials {
access_token : String, access_token : String,
account_id : String, pub account_id : String,
device_id : String, device_id : String,
secret: String,
} }
impl DeviceCredentials { impl DeviceCredentials {
pub fn new() -> DeviceCredentials { pub fn new() -> DeviceCredentials {
DeviceCredentials{ DeviceCredentials{
device_id: String::new(), device_id: String::new(),
account_id: String::new(), account_id: String::new(),
access_token: String::new(), access_token: String::new(),
secret: String::new(),
} }
} }
pub fn get_access_token_and_account_id(&mut self, http_client: &Client, authcode: &str) { pub fn get_access_token_and_account_id(&mut self, http_client: &Client, authcode: &str) {
if authcode.is_empty() { if authcode.is_empty() {
error!("Authentication Code cannot be empty"); error!("Authentication Code cannot be empty");
return; return;
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct ResponseStruct { struct ResponseStruct {
access_token: String, access_token: String,
@ -77,9 +80,9 @@ impl DeviceCredentials {
_ => { error!("Failed to get access token!"); }, _ => { error!("Failed to get access token!"); },
} }
} }
pub fn get_device_auth(&mut self, http_client: &Client) { pub fn get_device_auth_and_secret(&mut self, http_client: &Client) {
if self.access_token.is_empty() || self.account_id.is_empty() { if self.access_token.is_empty() || self.account_id.is_empty() {
error!("Device access token cannot be empty!"); error!("Device access token cannot be empty!");
return; return;
@ -94,7 +97,7 @@ impl DeviceCredentials {
it.starts_with("one thing"); it.starts_with("one thing");
// Just discovered String.starts_with() KEKW // Just discovered String.starts_with() KEKW
*/ */
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct CreatedObject { struct CreatedObject {
location: String, location: String,
@ -123,6 +126,7 @@ impl DeviceCredentials {
match response_data.json::<ResponseStruct>().ok() { match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => { Some(response_json) => {
self.device_id = response_json.deviceId; self.device_id = response_json.deviceId;
self.secret = response_json.secret;
} }
None => { None => {
error!("Failed to parse device_id!"); error!("Failed to parse device_id!");
@ -132,13 +136,13 @@ impl DeviceCredentials {
_ => { error!("Failed to get device_id!"); }, _ => { error!("Failed to get device_id!"); },
} }
} }
pub fn get_device_auth_from(&mut self, http_client: &Client, access_token: &str, account_id: &str) { 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() { if access_token.is_empty() || account_id.is_empty() {
error!("Device access token cannot be empty!"); error!("Device access token cannot be empty!");
return; return;
} }
let mut url : String = String::from("https://account-public-service-prod.ol.epicgames.com/account/api/public/account/"); 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(account_id);
url.push_str("/deviceAuth"); url.push_str("/deviceAuth");
@ -177,6 +181,7 @@ impl DeviceCredentials {
match response_data.json::<ResponseStruct>().ok() { match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => { Some(response_json) => {
self.device_id = response_json.deviceId; self.device_id = response_json.deviceId;
self.secret = response_json.secret;
} }
None => { None => {
error!("Failed to parse device_id!"); error!("Failed to parse device_id!");
@ -186,8 +191,135 @@ impl DeviceCredentials {
_ => { error!("Failed to get device_id!"); }, _ => { error!("Failed to get device_id!"); },
} }
} }
pub fn get_exchange_code() { pub fn get_exchange_code() -> String {
todo!(); todo!();
} }
} }
#[derive(Debug)]
pub struct TemporaryCredentials {
access_token : String,
pub exchange_code : String,
}
impl TemporaryCredentials {
pub fn new() -> TemporaryCredentials {
TemporaryCredentials {
access_token : String::new(),
exchange_code : String::new(),
}
}
pub fn get_access_token(&mut self, http_client: &Client, device_credentials: &DeviceCredentials) {
#[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,
product_id: String,
application_id: String,
acr: String,
auth_time: String
}
let mut request_body = String::new();
{
// Grant type
request_body.push_str("grant_type=device_auth"
.trim());
// AccountID
request_body.push_str("&account_id=");
request_body.push_str(device_credentials.account_id
.as_str()
.trim());
// DeviceID
request_body.push_str("&device_id=");
request_body.push_str(device_credentials.device_id
.as_str()
.trim());
// Secret
request_body.push_str("&secret=");
request_body.push_str(device_credentials.secret
.as_str()
.trim());
request_body = request_body.trim().to_string();
}
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)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization",
"Basic M2Y2OWU1NmM3NjQ5NDkyYzhjYzI5ZjFhZjA4YThhMTI6YjUxZWU5Y2IxMjIzNGY1MGE2OWVmYTY3ZWY1MzgxMmU=")
.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) {
#[derive(Debug,Deserialize)]
struct ResponseStruct {
expiresInSeconds: u16,
code: String,
creatingClientId: String,
}
let mut bearer_header = String::from("Bearer ");
bearer_header.push_str(self.access_token.as_str());
let url: &str = "https://account-public-service-prod.ol.epicgames.com/account/api/oauth/exchange";
let response = Client::get(&http_client, url)
.header("Authorization", bearer_header.as_str())
.send();
match response {
Ok(response_data) => {
match response_data.json::<ResponseStruct>().ok() {
Some(response_json) => {
self.exchange_code = response_json.code;
}
None => {
error!("Failed to parse 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

@ -1,10 +1,15 @@
mod auth; mod auth;
use std::process::exit;
use log::*; use log::*;
use colog; use colog;
use std::env::args; use std::env::args;
use std::io::Write; use std::io::Write;
use crate::auth::DeviceCredentials;
use std::process::Command;
use std::process::Stdio;
use crate::auth::*;
fn main() { fn main() {
/* Initial initializations */ /* Initial initializations */
@ -55,14 +60,82 @@ fn main() {
print!("Insert AuthCode > "); print!("Insert AuthCode > ");
std::io::stdout().flush().unwrap(); std::io::stdout().flush().unwrap();
// 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 credentials : DeviceCredentials = DeviceCredentials::new(); let mut persistent_credentials: DeviceCredentials = DeviceCredentials::new();
credentials.get_access_token_and_account_id(&http_client, &auth_code); {
credentials.get_device_auth(&http_client); persistent_credentials.get_access_token_and_account_id(&http_client, &auth_code);
dbg!(&credentials); 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);
}
/* Game Launching*/ /* Game Launching*/
let mut auth_password_argument = String::from("-AUTH_PASSWORD=");
auth_password_argument.push_str(login_credentials.exchange_code.as_str());
let mut uid_argument = String::from("-epicuserid=");
uid_argument.push_str(persistent_credentials.account_id.as_str());
/*let game_path = "D:\\Games\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe";
let game_arguments = vec![
"/d",
"D:\\Games\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe", "FortniteLauncher.exe",
"-obfuscationid=iDkaKzl08diwOpawKkaeEkwihUB0Og",
"-AUTH_LOGIN=unused",
&auth_password_argument,
"-AUTH_TYPE=exchangecode",
"-epicapp=Fortnite",
"-epicenv=Prod",
"-EpicPortal",
"-steamimportavailable",
&uid_argument,
"-epiclocale=en",
"-epicsandboxid=fn",
];*/
/*
Command::new(game_path)
.args(game_arguments)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.unwrap();
*/
let command = Command::new("cmd")
.arg("/C") // '/C' executes the command and terminates the command shell
.arg("start")
.arg("/d")
.arg("D:\\Games\\Epic Games\\Fortnite\\FortniteGame\\Binaries\\Win64") // Path to the directory
.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(&uid_argument)
.spawn();
match command {
Ok(mut child) => {
// Optionally, you can wait for the process to complete
let status = child.wait().expect("Failed to wait on child");
println!("Command executed with status: {}", status);
}
Err(e) => {
eprintln!("Error executing command: {}", e);
exit(1);
}
}
} }