Skip to content

Commit

Permalink
Make Proxy Load Bootstrap
Browse files Browse the repository at this point in the history
  • Loading branch information
RinLovesYou committed Nov 21, 2023
1 parent fb34aec commit dcfdbc9
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 21 deletions.
92 changes: 75 additions & 17 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Rust/MelonProxy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ readme = "../README.md"
thiserror = "1.0.48"
melon_proxy-sys = { path = "../MelonProxy-sys" }
utf16string = "0.2.0"
windows = { version = "0.51.1", features = ["Win32_Foundation", "Win32_System", "Win32_System_LibraryLoader"] }
windows = { version = "0.52.0", features = ["Win32_Foundation", "Win32_System", "Win32_System_LibraryLoader"] }
libloading = "0.8.0"
msgbox = "0.7.0"

#[target.'cfg(windows)'.dependencies]

Expand Down
4 changes: 2 additions & 2 deletions Rust/MelonProxy/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[cfg(msvc)]
#[cfg(windows)]
fn main() {
println!("cargo:warning=Linking Exports File..");
use std::path::Path;
Expand All @@ -10,7 +10,7 @@ fn main() {
);
}

#[cfg(not(msvc))]
#[cfg(not(windows))]
fn main() {

}
40 changes: 40 additions & 0 deletions Rust/MelonProxy/src/core.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::{error::Error, sync::{LazyLock, Mutex}, path::PathBuf};

use libloading::Library;

use crate::utils::files;

pub static BOOTSTRAP: LazyLock<Mutex<Option<Library>>> = LazyLock::new(|| Mutex::new(None));

pub fn init() -> Result<(), Box<dyn Error>> {
let args: Vec<String> = std::env::args().collect();

//TODO: Support UTF-16 (it will suck)
let mut base_dir = std::env::current_dir()?;
let mut no_mods = false;

for arg in args.iter() {
if arg.starts_with("--melonloader.basedir") {
let a: Vec<&str> = arg.split("=").collect();
base_dir = PathBuf::from(a[1]);
}

if arg.contains("--no-mods") {
no_mods = true;
}
}

//return Ok, and silently stop loading MelonLoader, if the user has specified to not load mods,
//or if the game is not a Unity game
if no_mods {
return Ok(());
}

let bootstrap_path = files::get_bootstrap_path(&base_dir)?;

unsafe {
*BOOTSTRAP.try_lock()? = Some(Library::new(&bootstrap_path)?);
}

Ok(())
}
6 changes: 5 additions & 1 deletion Rust/MelonProxy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ use melon_proxy_sys::proxy;
pub use windows::Win32::Foundation::HINSTANCE;

pub mod proxy;
pub mod utils;
pub mod core;

#[proxy]
fn main() {
println!("hello world");
core::init().unwrap_or_else(|e| {
internal_failure!("Failed to initialize MelonLoader: {}", e);
});
}
23 changes: 23 additions & 0 deletions Rust/MelonProxy/src/utils/assert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//! lets us throw an internal failure
/// Throws an internal failure with the given message
///
/// This creates a message box, and then panics.
/// It uses the same syntax as _format!_
///
/// # Examples
///
/// ```
/// # use utils::assert;
/// assert::internal_failure!("This is an internal failure");
/// ```
#[macro_export]
macro_rules! internal_failure {
($($arg:tt)*) => {{
let msg = &format_args!($($arg)*).to_string();

std::println!("{}", msg);
let _ = msgbox::create("Internal Failure", msg, msgbox::IconType::Error);
std::process::exit(1);
}};
}
9 changes: 9 additions & 0 deletions Rust/MelonProxy/src/utils/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::path::PathBuf;

use thiserror::Error;

#[derive(Debug, Error)]
pub enum ProxyError {
#[error("failed to find Bootstrap at \"{0}\" please make sure you have installed MelonLoader correctly")]
BootstrapNotFound(PathBuf),
}
20 changes: 20 additions & 0 deletions Rust/MelonProxy/src/utils/files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use std::{env::consts::DLL_EXTENSION, path::PathBuf};

use super::errors::ProxyError;

/// search for Bootstrap in the given path
pub fn get_bootstrap_path(base_path: &PathBuf) -> Result<PathBuf, ProxyError> {
let bootstrap_names = ["melon_bootstrap", "libmelon_bootstrap"]; //by convention, on unix, the library is prefixed with "lib"

let path = base_path.join("MelonLoader").join("Dependencies");

for name in bootstrap_names.iter() {
let bootstrap_path = path.join(name).with_extension(DLL_EXTENSION);

if bootstrap_path.exists() {
return Ok(bootstrap_path);
}
}

Err(ProxyError::BootstrapNotFound(base_path.to_owned()))
}
3 changes: 3 additions & 0 deletions Rust/MelonProxy/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod assert;
pub mod errors;
pub mod files;

0 comments on commit dcfdbc9

Please sign in to comment.