Skip to content

Commit

Permalink
dedicated linux server support
Browse files Browse the repository at this point in the history
  • Loading branch information
ToniMacaroni committed Mar 24, 2024
1 parent 9204601 commit db997e0
Show file tree
Hide file tree
Showing 19 changed files with 394 additions and 141 deletions.
4 changes: 3 additions & 1 deletion Bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ libc = "0.2.140"
dobby-rs = { git = "https://github.com/RinLovesYou/dobby-rs" }
libc-stdhandle = "0.1.0"
netcorehost = "0.13.1"
zip = "0.6.6"
ureq = "2.9.6"

[target.'cfg(windows)'.dependencies]
windows = { version = "0.46.0", features = [
Expand All @@ -28,4 +30,4 @@ windows = { version = "0.46.0", features = [
]}

[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib"]
64 changes: 57 additions & 7 deletions Bootstrap/src/base_assembly/dotnet.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#![allow(unused_imports)]

use lazy_static::lazy_static;
use netcorehost::{nethost, pdcstr};
use netcorehost::{hostfxr, nethost, pdcstr};
use std::{
ffi::c_void,
ptr::{addr_of, addr_of_mut, null_mut},
sync::RwLock,
ffi::c_void, fs::{self, File}, io::{copy, Read}, path::Path, ptr::{addr_of, addr_of_mut, null_mut}, sync::RwLock
};

use crate::{
debug,
errors::{dotneterr::DotnetErr, DynErr},
icalls, melonenv,
icalls, melonenv::{self, context::IS_SERVER},
utils::{self, strings::wide_str},
};

Expand Down Expand Up @@ -48,14 +48,21 @@ lazy_static! {
pub fn init() -> Result<(), DynErr> {
let runtime_dir = melonenv::paths::runtime_dir()?;

let hostfxr = nethost::load_hostfxr().map_err(|_| DotnetErr::FailedHostFXRLoad)?;
let mut hostfxr = nethost::load_hostfxr();
if hostfxr.is_err() {
println!("Failed to load hostfxr, attempting to setup .NET runtime...");
setup_dotnet()?;
hostfxr = nethost::load_hostfxr();
}

//let hostfxr = nethost::load_hostfxr().map_err(|_| DotnetErr::FailedHostFXRLoad)?;

let config_path = runtime_dir.join("RedLoader.runtimeconfig.json");
if !config_path.exists() {
return Err(DotnetErr::RuntimeConfig.into());
}

let context = hostfxr.initialize_for_runtime_config(utils::strings::pdcstr(config_path)?)?;
let context = hostfxr.map_err(|_| DotnetErr::FailedHostFXRLoad)?.initialize_for_runtime_config(utils::strings::pdcstr(config_path)?)?;

let loader = context.get_delegate_loader_for_assembly(utils::strings::pdcstr(
runtime_dir.join("NativeHost.dll"),
Expand Down Expand Up @@ -129,3 +136,46 @@ pub fn start() -> Result<(), DynErr> {

Ok(())
}

fn setup_dotnet() -> Result<(), DynErr> {
let netrt_path = Path::new("dotnetrt");

if Path::exists(netrt_path) {
std::env::set_var("DOTNET_ROOT", netrt_path.canonicalize()?);
return Ok(());
}

let response = ureq::get("https://dotnetcli.azureedge.net/dotnet/Runtime/6.0.0/dotnet-runtime-6.0.0-win-x64.zip").call()?;

let archive_path = Path::new("dotnet.zip");

let _ = copy(&mut response.into_reader(), &mut File::create(archive_path)?)?;

fs::create_dir_all(&netrt_path)?;

let file = File::open(&archive_path)?;
let mut archive = zip::ZipArchive::new(file)?;

for i in 0..archive.len() {
let mut file = archive.by_index(i)?;
let file_path = netrt_path.join(file.name());

if file.is_dir() {
fs::create_dir_all(&file_path)?;
} else {
if let Some(parent) = file_path.parent() {
if !parent.exists() {
fs::create_dir_all(&parent)?;
}
}
let mut extracted_file = fs::File::create(&file_path)?;
let _ = std::io::copy(&mut file, &mut extracted_file)?;
}
}

fs::remove_file(&archive_path)?;

std::env::set_var("DOTNET_ROOT", netrt_path.canonicalize()?);

Ok(())
}
2 changes: 1 addition & 1 deletion Bootstrap/src/base_assembly/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn init(runtime: &FerrexRuntime) -> Result<(), DynErr> {
debug!("Initializing BaseAssembly")?;

//get MelonLoader.dll's path and confirm it exists
let mut melonloader_dll = melonenv::paths::MELONLOADER_FOLDER.clone();
let mut melonloader_dll = melonenv::paths::REDLOADER_FOLDER.clone();
melonloader_dll.extend(&["net35", "MelonLoader.dll"]);

if !melonloader_dll.exists() {
Expand Down
15 changes: 1 addition & 14 deletions Bootstrap/src/console/mod.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
pub mod os;
use lazy_static::lazy_static;

#[cfg(all(unix))]
use os::unix as imp;

#[cfg(all(windows))]
use os::windows as imp;

use crate::{errors::DynErr, hide_console};

lazy_static! {
static ref IS_SERVER: bool = check_for_server();
}

pub fn check_for_server() -> bool {
std::env::current_exe()
.ok()
.and_then(|pb| pb.file_name().map(|s| s.to_os_string()))
.and_then(|s| s.into_string().ok())
.map(|s| s == "SonsOfTheForestDS.exe").unwrap()
}
use crate::{errors::DynErr, hide_console, melonenv::context::IS_SERVER};

pub fn init() -> Result<(), DynErr> {
if *IS_SERVER {
Expand Down
13 changes: 13 additions & 0 deletions Bootstrap/src/melonenv/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use lazy_static::lazy_static;

lazy_static! {
pub static ref IS_SERVER: bool = check_for_server();
}

pub fn check_for_server() -> bool {
std::env::current_exe()
.ok()
.and_then(|pb| pb.file_name().map(|s| s.to_os_string()))
.and_then(|s| s.into_string().ok())
.map(|s| s == "SonsOfTheForestDS.exe").unwrap()
}
1 change: 1 addition & 0 deletions Bootstrap/src/melonenv/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod args;
pub mod macros;
pub mod paths;
pub mod context;
8 changes: 4 additions & 4 deletions Bootstrap/src/melonenv/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ lazy_static! {
internal_failure!("Failed to get game directory: {}", e.to_string());
}))
};
pub static ref MELONLOADER_FOLDER: W<PathBuf> = W(BASE_DIR.join("_RedLoader"));
pub static ref DEPENDENCIES_FOLDER: W<PathBuf> = W(MELONLOADER_FOLDER.join("Dependencies"));
pub static ref REDLOADER_FOLDER: W<PathBuf> = W(BASE_DIR.join("_RedLoader"));
pub static ref DEPENDENCIES_FOLDER: W<PathBuf> = W(REDLOADER_FOLDER.join("Dependencies"));
pub static ref SUPPORT_MODULES_FOLDER: W<PathBuf> = W(DEPENDENCIES_FOLDER.join("SupportModules"));
pub static ref PRELOAD_DLL: W<PathBuf> = W(SUPPORT_MODULES_FOLDER.join("Preload.dll"));
}

pub fn runtime_dir() -> Result<PathBuf, DynErr> {
let runtime = runtime!()?;

let mut path = MELONLOADER_FOLDER.clone();
let mut path = REDLOADER_FOLDER.clone();

match runtime.get_type() {
RuntimeType::Mono(_) => path.push("net35"),
Expand Down Expand Up @@ -58,7 +58,7 @@ pub fn get_managed_dir() -> Result<PathBuf, DynErr> {
match managed_path.exists() {
true => Ok(managed_path),
false => {
let managed_path = base_folder.join("MelonLoader").join("Managed");
let managed_path = base_folder.join("_RedLoader").join("Managed");

match managed_path.exists() {
true => Ok(managed_path),
Expand Down
12 changes: 5 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
- Added `aighostplayer` command back in.
- Removed `addcharacter` and `goto` commands.
- Added a list of item identifiers (`ItemTools.Identifers`).
- Added `DebugTools.Inspect` to inspect an object in Unity Explorer without having a dependency on it.
- Added `finishblueprints` command to finish all blueprints in a radius.
- Overhaul of SoundTools (@codengine).
- Various changes to the SDK.
- Added dedicated server support for linux.
- Auto download of minimal local dotnet 6 installation if hostfxr can not be found.
- Removed .net 4.7.2 dependency.
- Make generating hooks opt-in.
- Bumped Cpp2IL version to `2022.1.0-pre-release.14`
Loading

0 comments on commit db997e0

Please sign in to comment.