Skip to content

Commit

Permalink
Merge pull request #522 from RinLovesYou/alpha-development
Browse files Browse the repository at this point in the history
Alpha development
  • Loading branch information
RinLovesYou authored Sep 13, 2023
2 parents bb5202b + d1417d0 commit afdecfd
Show file tree
Hide file tree
Showing 20 changed files with 850 additions and 807 deletions.
5 changes: 3 additions & 2 deletions Bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ clap = { git = "https://github.com/RinLovesYou/clap", features = ["derive"] }
libc = "0.2.140"
dobby-rs = { git = "https://github.com/RinLovesYou/dobby-rs" }
libc-stdhandle = "0.1.0"
netcorehost = "0.13.1"
netcorehost = "0.15.1"
exe = "0.5.6"

[target.'cfg(windows)'.dependencies]
windows = { version = "0.46.0", features = [
windows = { version = "0.51.0", features = [
"Win32_Foundation",
"Win32_System_Console",
"Win32_UI_WindowsAndMessaging"
Expand Down
4 changes: 3 additions & 1 deletion Bootstrap/src/base_assembly/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use unity_rs::{
runtime::FerrexRuntime,
};

use crate::{debug, errors::DynErr, melonenv, runtime};
use crate::{debug, errors::DynErr, melonenv::{self, paths}, runtime};

lazy_static! {
pub static ref MONO_PRESTART: Mutex<UnityMethod> =
Expand All @@ -23,6 +23,8 @@ pub fn init(runtime: &FerrexRuntime) -> Result<(), DynErr> {

debug!("Initializing BaseAssembly")?;

let _runtime_dir = paths::runtime_dir()?;

//get MelonLoader.dll's path and confirm it exists
let mut melonloader_dll = melonenv::paths::MELONLOADER_FOLDER.clone();
melonloader_dll.extend(&["net35", "MelonLoader.dll"]);
Expand Down
10 changes: 4 additions & 6 deletions Bootstrap/src/console/os/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ lazy_static! {

pub unsafe fn init() -> Result<(), DynErr> {
// creates a console window, if one already exists it'll just return true.
if !AllocConsole().as_bool() {
return Err(ConsoleError::FailedToAllocateConsole.into());
}
AllocConsole()?;

// store the console window handle
let mut window = WINDOW.try_lock()?;
Expand All @@ -39,7 +37,7 @@ pub unsafe fn init() -> Result<(), DynErr> {
}

// this lets us hook into console close events, and run some cleanup logic.
if SetConsoleCtrlHandler(Some(ctrl_handler_hook), Foundation::TRUE) == Foundation::FALSE {
if SetConsoleCtrlHandler(Some(ctrl_handler_hook), Foundation::TRUE).is_err() {
return Err(ConsoleError::FailedToSetConsoleCtrlHandler.into());
}

Expand Down Expand Up @@ -80,12 +78,12 @@ pub unsafe fn init() -> Result<(), DynErr> {

mode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;

if SetConsoleMode(*output_handle, mode) != Foundation::TRUE {
if SetConsoleMode(*output_handle, mode).is_err() {
mode &= !(ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
} else {
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;

if SetConsoleMode(*output_handle, mode) != Foundation::TRUE {
if SetConsoleMode(*output_handle, mode).is_err() {
mode &= !ENABLE_VIRTUAL_TERMINAL_PROCESSING;
}
}
Expand Down
28 changes: 14 additions & 14 deletions Bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#![allow(non_snake_case)]
#![deny(
missing_debug_implementations,
unused_results,
warnings,
clippy::extra_unused_lifetimes,
clippy::from_over_into,
clippy::needless_borrow,
clippy::new_without_default,
clippy::useless_conversion
)]
#![forbid(rust_2018_idioms)]
#![allow(clippy::inherent_to_string, clippy::type_complexity, improper_ctypes)]
#![cfg_attr(docsrs, feature(doc_cfg))]
// #![allow(non_snake_case)]
// #![deny(
// missing_debug_implementations,
// unused_results,
// warnings,
// clippy::extra_unused_lifetimes,
// clippy::from_over_into,
// clippy::needless_borrow,
// clippy::new_without_default,
// clippy::useless_conversion
// )]
// #![forbid(rust_2018_idioms)]
// #![allow(clippy::inherent_to_string, clippy::type_complexity, improper_ctypes)]
// #![cfg_attr(docsrs, feature(doc_cfg))]

pub mod base_assembly;
pub mod console;
Expand Down
2 changes: 1 addition & 1 deletion Bootstrap/src/logging/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl std::convert::TryFrom<u8> for LogLevel {

macro_rules! log_path {
() => {
std::env::current_dir()?.join("MelonLoader").join("Latest-Bootstrap.log")
$crate::melonenv::paths::BASE_DIR.clone().join("MelonLoader").join("Latest-Bootstrap.log")
};
}

Expand Down
28 changes: 16 additions & 12 deletions Bootstrap/src/melonenv/macros.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
#[macro_export]
macro_rules! debug_enabled {
() => {
() => {{
if cfg!(debug_assertions) {
true
} else {
$crate::melonenv::args::ARGS.debug.is_some_and(|b| b)
let args: Vec<String> = std::env::args().collect();
args.contains(&"--melonloader.debug".to_string())
}
};
}};
}

#[macro_export]
macro_rules! should_set_title {
() => {
!$crate::melonenv::args::ARGS.console_dst.is_some_and(|b| b)
};
() => {{
let args: Vec<String> = std::env::args().collect();
!args.contains(&"--melonloader.consoledst".to_string())
}};
}

#[macro_export]
macro_rules! console_on_top {
() => {
$crate::melonenv::args::ARGS.console_on_top.is_some_and(|b| b)
};
() => {{
let args: Vec<String> = std::env::args().collect();
args.contains(&"--melonloader.consoleontop".to_string())
}};
}

#[macro_export]
macro_rules! hide_console {
() => {
$crate::melonenv::args::ARGS.hide_console.is_some_and(|b| b)
};
() => {{
let args: Vec<String> = std::env::args().collect();
args.contains(&"--melonloader.hideconsole".to_string())
}};
}
33 changes: 23 additions & 10 deletions Bootstrap/src/melonenv/paths.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
use std::path::PathBuf;
use std::path::{PathBuf, Path};

use lazy_static::lazy_static;
use unity_rs::runtime::RuntimeType;

use crate::{errors::DynErr, internal_failure, runtime, constants::W};
use crate::{errors::DynErr, internal_failure, runtime, constants::W, utils::runtime::{self, NetstandardVersion}};

use super::args::ARGS;

lazy_static! {
pub static ref BASE_DIR: W<PathBuf> = {
match ARGS.base_dir {
Some(ref path) => W(PathBuf::from(path.clone())),
None => W(std::env::current_dir().unwrap_or_else(|e| {
internal_failure!("Failed to get base directory: {}", e.to_string());
})),
let args: Vec<String> = std::env::args().collect();
let mut base_dir = std::env::current_dir().unwrap_or_else(|e|internal_failure!("Failed to get base dir: {e}"));
for arg in args.iter() {
if arg.starts_with("--melonloader.basedir") {
let a: Vec<&str> = arg.split("=").collect();
base_dir = PathBuf::from(a[1]);
}
}

W(base_dir)
};
pub static ref GAME_DIR: W<PathBuf> = {
W(std::env::current_dir().unwrap_or_else(|e| {
internal_failure!("Failed to get game directory: {}", e.to_string());
}))
let args: Vec<String> = std::env::args().collect();
let mut base_dir = std::env::current_dir().unwrap_or_else(|e|internal_failure!("Failed to get game dir: {e}"));
for arg in args.iter() {
if arg.starts_with("--melonloader.basedir") {
let a: Vec<&str> = arg.split("=").collect();
base_dir = PathBuf::from(a[1]);
}
}

W(base_dir)
};
pub static ref MELONLOADER_FOLDER: W<PathBuf> = W(BASE_DIR.join("MelonLoader"));
pub static ref DEPENDENCIES_FOLDER: W<PathBuf> = W(MELONLOADER_FOLDER.join("Dependencies"));
Expand All @@ -32,6 +43,8 @@ pub fn runtime_dir() -> Result<PathBuf, DynErr> {

let mut path = MELONLOADER_FOLDER.clone();

//let version = runtime::get_netstandard_version()?;

match runtime.get_type() {
RuntimeType::Mono(_) => path.push("net35"),
RuntimeType::Il2Cpp(_) => path.push("net6"),
Expand Down
82 changes: 81 additions & 1 deletion Bootstrap/src/utils/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::{error::Error, collections::HashMap, io, path::Path};

use exe::{ImageDirectoryEntry, ResourceDirectory, VecPE, PE, ImportDirectory, ImportData, CCharString, ImageDataDirectory, ImageResourceDirectory};
use unity_rs::runtime::FerrexRuntime;

use crate::errors::DynErr;
use crate::{errors::DynErr, log, melonenv::paths};

#[allow(dead_code)]
pub static mut RUNTIME: Option<FerrexRuntime> = None;
Expand All @@ -21,3 +24,80 @@ pub fn get_runtime() -> Result<&'static FerrexRuntime, DynErr> {
Ok(RUNTIME.as_ref().ok_or("Failed to get runtime")?)
}
}

#[derive(Debug)]
pub enum NetstandardVersion {
Old,
New,
}

impl Default for PeFileInfo {
fn default () -> PeFileInfo {
PeFileInfo {
product_version: String::new(),
original_filename: String::new(),
file_description: String::new(),
file_version: String::new(),
product_name: String::new(),
company_name: String::new(),
internal_name: String::new(),
legal_copyright: String::new()
}
}
}
#[derive(Clone)]
pub struct PeFileInfo {
pub product_version: String,
pub original_filename: String,
pub file_description: String,
pub file_version: String,
pub product_name: String,
pub company_name: String,
pub internal_name: String,
pub legal_copyright: String
}

pub fn get_netstandard_version() -> Result<NetstandardVersion, Box<dyn Error>> {
let netstandard = paths::get_managed_dir()?.join("netstandard.dll");
if !netstandard.exists() {
return Ok(NetstandardVersion::Old);
}

let file_info = get_pe_file_info(&netstandard)?;

match file_info.file_version.as_str() {
"2.1.0.0" => Ok(NetstandardVersion::New),
_ => Ok(NetstandardVersion::Old)
}
}

fn get_pe_file_info(path: &Path) -> io::Result<PeFileInfo> {
let mut file_info = PeFileInfo::default();
let Ok(pefile) = exe::VecPE::from_disk_file(path) else { return Ok(file_info) };
let Ok(vs_version_check) = exe::VSVersionInfo::parse(&pefile) else { return Ok(file_info) };
let vs_version = vs_version_check;
if let Some(string_file_info) = vs_version.string_file_info {
let Ok(string_map) = string_file_info.children[0].string_map() else { return Ok(file_info) };
file_info.product_version = get_hashmap_value(&string_map, "ProductVersion")?;
file_info.original_filename = get_hashmap_value(&string_map, "OriginalFilename")?;
file_info.file_description = get_hashmap_value(&string_map, "FileDescription")?;
file_info.file_version = get_hashmap_value(&string_map, "FileVersion")?;
file_info.product_name = get_hashmap_value(&string_map, "ProductName")?;
file_info.company_name = get_hashmap_value(&string_map, "CompanyName")?;
file_info.internal_name = get_hashmap_value(&string_map, "InternalName")?;
file_info.legal_copyright = get_hashmap_value(&string_map, "LegalCopyright")?;
}
Ok(file_info)
}


fn get_hashmap_value(
string_map: &HashMap<String, String>,
value_name: &str
) -> io::Result<String>
{
let _v = match string_map.get(value_name) {
Some(v) => return Ok(v.to_string()),
None => return Ok("".to_string())
};
}
Loading

0 comments on commit afdecfd

Please sign in to comment.