Skip to content

Commit

Permalink
Add autostart version
Browse files Browse the repository at this point in the history
  • Loading branch information
MolotovCherry committed Nov 10, 2024
1 parent 2ce37a2 commit fa88edd
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 9 deletions.
95 changes: 95 additions & 0 deletions crates/yabg3nml/src/bin/bg3_autostart.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::{
env,
os::windows::process::CommandExt as _,
path::Path,
process::{Command, ExitCode},
};

use shared::{config::get_config, popup::fatal_popup};
use windows::Win32::System::{
Diagnostics::Debug::DebugActiveProcessStop,
Threading::{DEBUG_ONLY_THIS_PROCESS, DEBUG_PROCESS},
};
use yabg3nml::get_game_binary_paths;

fn main() -> ExitCode {
// [this_exe_path, bg3_exe_path, ..args]
let args = env::args().skip(2);

let Some(bg3_exe) = env::args().nth(1) else {
fatal_popup(
"No direct launch",
"This autostart program is not a launcher. Please check instructions for how to use it. (nth(1) missing)",
);
};

let Some(bg3_exe) = Path::new(&bg3_exe).file_name().map(|p| p.to_string_lossy()) else {
fatal_popup(
"No direct launch",
"This autostart program is not a launcher. Please check instructions for how to use it. (file_name() missing)",
);
};

let config = match get_config() {
Ok(v) => v,
Err(e) => {
fatal_popup("Error reading config", format!("Failed to get config file. Most likely either it failed to read the file, or your config file is malformed.\n\nError: {e}"));
}
};

let exes = get_game_binary_paths(config);

// validate it's actually a bg3 executable
let is_bg3 = ["bg3.exe", "bg3_dx11.exe"].contains(&&*bg3_exe);
if !is_bg3 {
fatal_popup(
"No direct launch",
"This autostart program is not a launcher. Please check instructions for how to use it. (this is not a bg3 exe)",
);
}

let bg3_path = match &*bg3_exe {
"bg3.exe" => exes.bg3,
"bg3_dx11.exe" => exes.bg3_dx11,
_ => fatal_popup(
"Unexpected error",
format!("bg3_exe is not one of two bg3 exes. This should never happen. exe: {bg3_exe}"),
),
};

let mut child = match Command::new(bg3_path)
.args(args)
// bypass IFEO on this launch
.creation_flags(DEBUG_PROCESS.0 | DEBUG_ONLY_THIS_PROCESS.0)
.envs(env::vars())
.spawn()
{
Ok(v) => v,
Err(e) => {
fatal_popup(
"Spawn failure",
format!("Failed to spawn game process: {e}"),
);
}
};

let pid = child.id();
// stop debugging
if let Err(e) = unsafe { DebugActiveProcessStop(pid) } {
fatal_popup(
"DebugActiveProcessStop failed",
format!("DebugActiveProcessStop failed: {e}"),
);
}

if let Err(e) = yabg3nml::autostart(pid) {
fatal_popup("autostart failure", format!("{e}"));
}

child
.wait()
.map(|s| ExitCode::from(s.code().unwrap_or(1).clamp(u8::MIN as _, u8::MAX as _) as u8))
.unwrap_or(ExitCode::FAILURE)
}
9 changes: 5 additions & 4 deletions crates/yabg3nml/src/bin/bg3_injector.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use eyre::Result;

use shared::popup::fatal_popup;
use yabg3nml::RunType;

fn main() -> Result<()> {
yabg3nml::run(RunType::Injector)
fn main() {
if let Err(e) = yabg3nml::run(RunType::Injector) {
fatal_popup("injector failure", format!("{e}"));
}
}
9 changes: 5 additions & 4 deletions crates/yabg3nml/src/bin/bg3_watcher.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use eyre::Result;

use shared::popup::fatal_popup;
use yabg3nml::RunType;

fn main() -> Result<()> {
yabg3nml::run(RunType::Watcher)
fn main() {
if let Err(e) = yabg3nml::run(RunType::Watcher) {
fatal_popup("watcher failure", format!("{e}"));
}
}
2 changes: 1 addition & 1 deletion crates/yabg3nml/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use argh::FromArgs;

/// A simple, non-invasive BG3 native mod loader
#[derive(FromArgs)]
#[derive(Default, FromArgs)]
pub struct Args {
/// show console window
#[argh(switch)]
Expand Down
29 changes: 29 additions & 0 deletions crates/yabg3nml/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ use setup::init;
use single_instance::SingleInstance;
use tray::AppTray;

use process_watcher::Pid;

#[allow(unused)]
pub use paths::get_game_binary_paths;

#[derive(Copy, Clone, Debug)]
pub enum RunType {
Watcher,
Expand Down Expand Up @@ -120,3 +125,27 @@ This can happen for 1 of 3 reasons:

Ok(())
}

pub fn autostart(pid: Pid) -> Result<()> {
// This prohibits multiple app instances
let _singleton = SingleInstance::new();
let _event = Event::new()?;

// DO NOT use argh, since it doesn't understand bg3 cli args
let args = Args::default();

let mut init = init(&args)?;
let _loader_lock = init.loader.file.take();
let _worker_guard = init.worker.take();

let res = run_loader(init.config, pid, &init.loader);
if let Err(e) = res {
error!(err = %e, "run_loader failed");
fatal_popup(
"run loader failed",
format!("run_loader unexpectedly failed. You should report this.\n\nError: {e}"),
);
}

Ok(())
}

0 comments on commit fa88edd

Please sign in to comment.