mirror of
https://github.com/a-mayb3/godo-launcher.git
synced 2026-03-21 18:05:39 +01:00
Managed to launch game correctly
This commit is contained in:
parent
1e35e945b4
commit
6f003af531
2 changed files with 224 additions and 19 deletions
140
src/auth.rs
140
src/auth.rs
|
|
@ -10,15 +10,18 @@ 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) {
|
||||||
|
|
@ -78,7 +81,7 @@ impl DeviceCredentials {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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!");
|
||||||
|
|
@ -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,7 +136,7 @@ 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!");
|
||||||
|
|
@ -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!");
|
||||||
|
|
@ -187,7 +192,134 @@ impl DeviceCredentials {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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!();}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
83
src/main.rs
83
src/main.rs
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue