Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions mbf-agent/src/handlers/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::path::{Path, PathBuf};
use crate::{
downloads,
mod_man::ModManager,
models::response::{self, ImportResultType, Response},
paths,
models::response::{self, ImportResultType, Response}, parameters::PARAMETERS
};
use anyhow::{anyhow, Context, Result};
use log::{debug, info, warn};
Expand All @@ -15,8 +14,8 @@ use mbf_zip::ZipFile;
/// # Returns
/// The [Response](requests::Response) to the request (variant `ImportResult`)
pub(super) fn handle_import_mod_url(from_url: String) -> Result<Response> {
std::fs::create_dir_all(paths::MBF_DOWNLOADS)?;
let download_path = Path::new(paths::MBF_DOWNLOADS).join("import_from_url");
std::fs::create_dir_all(&PARAMETERS.mbf_downloads)?;
let download_path = Path::new(&PARAMETERS.mbf_downloads).join("import_from_url");

info!("Downloading {}", from_url);
let filename: Option<String> =
Expand Down Expand Up @@ -183,7 +182,7 @@ fn attempt_song_import(from_path: PathBuf) -> Result<ImportResultType> {
let mut zip = ZipFile::open(song_handle).context("Song was invalid ZIP file")?;

if zip.contains_file("info.dat") || zip.contains_file("Info.dat") {
let extract_path = Path::new(paths::CUSTOM_LEVELS)
let extract_path = Path::new(&PARAMETERS.custom_levels)
.join(from_path.file_stem().expect("Must have file stem"));

if extract_path.exists() {
Expand Down
25 changes: 13 additions & 12 deletions mbf-agent/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use crate::{
mod_man::ModManager,
models::{
request::Request,
request::RequestEnum,
response::{self, Response},
},
}, parameters::PARAMETERS,
};
use anyhow::{anyhow, Context, Result};
use log::info;
Expand All @@ -28,11 +29,11 @@ mod utility;
/// # Returns
/// If successful, a [Response] to be sent back to the frontend.
pub fn handle_request(request: Request) -> Result<Response> {
match request {
Request::GetModStatus {
match request.request {
RequestEnum::GetModStatus {
override_core_mod_url,
} => mod_status::handle_get_mod_status(override_core_mod_url),
Request::Patch {
RequestEnum::Patch {
downgrade_to,
remodding,
manifest_mod,
Expand All @@ -49,15 +50,15 @@ pub fn handle_request(request: Request) -> Result<Response> {
override_core_mod_url,
vr_splash_path,
),
Request::GetDowngradedManifest { version } => {
RequestEnum::GetDowngradedManifest { version } => {
patching::handle_get_downgraded_manifest(version)
}
Request::RemoveMod { id } => mod_management::handle_remove_mod(id),
Request::SetModsEnabled { statuses } => mod_management::handle_set_mods_enabled(statuses),
Request::Import { from_path } => import::handle_import(from_path, None),
Request::ImportUrl { from_url } => import::handle_import_mod_url(from_url),
Request::FixPlayerData => utility::handle_fix_player_data(),
Request::QuickFix {
RequestEnum::RemoveMod { id } => mod_management::handle_remove_mod(id),
RequestEnum::SetModsEnabled { statuses } => mod_management::handle_set_mods_enabled(statuses),
RequestEnum::Import { from_path } => import::handle_import(from_path, None),
RequestEnum::ImportUrl { from_url } => import::handle_import_mod_url(from_url),
RequestEnum::FixPlayerData => utility::handle_fix_player_data(),
RequestEnum::QuickFix {
override_core_mod_url,
wipe_existing_mods,
} => utility::handle_quick_fix(override_core_mod_url, wipe_existing_mods),
Expand All @@ -72,7 +73,7 @@ pub fn handle_request(request: Request) -> Result<Response> {
/// An `Err` variant is returned on failure, for example if Beat Saber isn't installed or the result from `dumpsys` couldn't be parsed.
fn get_app_version_only() -> Result<String> {
let dumpsys_output = Command::new("dumpsys")
.args(["package", crate::APK_ID])
.args(["package", &PARAMETERS.apk_id])
.output()
.context("Invoking dumpsys")?;
let dumpsys_stdout =
Expand Down
10 changes: 5 additions & 5 deletions mbf-agent/src/handlers/patching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::Path;

use log::{info, warn};

use crate::{mod_man::ModManager, models::response::Response, patching, paths};
use crate::{mod_man::ModManager, models::response::Response, parameters::PARAMETERS, patching};
use anyhow::{anyhow, Context, Result};

/// Handles `GetDowngradedManifest` [Requests](requests::Request).
Expand Down Expand Up @@ -41,7 +41,7 @@ pub(super) fn handle_patch(
super::mod_status::get_app_info()?.ok_or(anyhow!("Cannot patch when app not installed"))?;
let res_cache = crate::load_res_cache()?;

std::fs::create_dir_all(paths::TEMP)?;
std::fs::create_dir_all(&PARAMETERS.temp)?;

// Either downgrade or just patch the current APK depending on the caller's choice.
let patching_result = if let Some(to_version) = &downgrade_to {
Expand All @@ -58,7 +58,7 @@ pub(super) fn handle_patch(
))?;

patching::downgrade_and_mod_apk(
Path::new(paths::TEMP),
Path::new(&PARAMETERS.temp),
&app_info,
version_diffs,
manifest_mod,
Expand All @@ -69,7 +69,7 @@ pub(super) fn handle_patch(
.context("Downgrading and patching APK")
} else {
patching::mod_current_apk(
Path::new(paths::TEMP),
Path::new(&PARAMETERS.temp),
&app_info,
manifest_mod,
repatch,
Expand All @@ -82,7 +82,7 @@ pub(super) fn handle_patch(
};

// No matter what, make sure that all temporary files are gone.
std::fs::remove_dir_all(paths::TEMP)?;
std::fs::remove_dir_all(&PARAMETERS.temp)?;
if let Some(splash_path) = vr_splash_path {
std::fs::remove_file(splash_path)?;
}
Expand Down
16 changes: 8 additions & 8 deletions mbf-agent/src/handlers/utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::path::Path;

use crate::{data_fix, mod_man::ModManager, models::response::Response, patching, paths};
use crate::{data_fix, mod_man::ModManager, models::response::Response, parameters::PARAMETERS, patching};
use anyhow::{anyhow, Context, Result};
use log::{debug, info, warn};

Expand Down Expand Up @@ -48,21 +48,21 @@ pub(super) fn handle_fix_player_data() -> Result<Response> {
patching::kill_app()?; // Kill app, in case it's still stuck in a hanging state

let mut did_work = false;
if Path::new(paths::DATAKEEPER_PLAYER_DATA).exists() {
if Path::new(&PARAMETERS.datakeeper_player_data).exists() {
info!("Fixing color scheme issues");
data_fix::fix_colour_schemes(paths::DATAKEEPER_PLAYER_DATA)?;
data_fix::fix_colour_schemes(&PARAMETERS.datakeeper_player_data)?;
did_work = true;
}

if Path::new(paths::PLAYER_DATA).exists() {
if Path::new(&PARAMETERS.player_data).exists() {
info!("Backing up player data");
patching::backup_player_data()?;

info!("Removing (potentially faulty) PlayerData.dat in game files");
debug!("(removing {})", paths::PLAYER_DATA);
std::fs::remove_file(paths::PLAYER_DATA).context("Deleting faulty player data")?;
if Path::new(paths::PLAYER_DATA_BAK).exists() {
std::fs::remove_file(paths::PLAYER_DATA_BAK)?;
debug!("(removing {})", &PARAMETERS.player_data);
std::fs::remove_file(&PARAMETERS.player_data).context("Deleting faulty player data")?;
if Path::new(&PARAMETERS.player_data_bak).exists() {
std::fs::remove_file(&PARAMETERS.player_data_bak)?;
}
did_work = true;
} else {
Expand Down
17 changes: 9 additions & 8 deletions mbf-agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ mod manifest;
mod mod_man;
mod models;
mod patching;
mod paths;
mod parameters;

use anyhow::{Context, Result};
use downloads::DownloadConfig;
use log::{debug, error, warn, Level};
use mbf_res_man::res_cache::ResCache;
use models::{request, response};
use parameters::{init_parameters, PARAMETERS};
use serde::{Deserialize, Serialize};
use std::{
io::{BufRead, BufReader, Write},
Expand All @@ -22,9 +23,6 @@ use std::{
sync,
};

/// The ID of the APK file that MBF manages.
pub const APK_ID: &str = "com.beatgames.beatsaber";

#[cfg(feature = "request_timing")]
use log::info;
#[cfg(feature = "request_timing")]
Expand All @@ -33,7 +31,7 @@ use std::time::Instant;
/// Attempts to delete legacy directories no longer used by MBF to free up space
/// Logs on failure
pub fn try_delete_legacy_dirs() {
for dir in paths::LEGACY_DIRS {
for dir in &PARAMETERS.legacy_dirs {
if Path::new(dir).exists() {
match std::fs::remove_dir_all(dir) {
Ok(_) => debug!("Successfully removed legacy dir {dir}"),
Expand Down Expand Up @@ -62,16 +60,16 @@ pub fn get_dl_cfg() -> &'static DownloadConfig<'static> {
/// Creates a ResCache for downloading files using mbf_res_man
/// This should be reused where possible.
pub fn load_res_cache() -> Result<ResCache<'static>> {
std::fs::create_dir_all(paths::RES_CACHE).expect("Failed to create resource cache folder");
std::fs::create_dir_all(&PARAMETERS.res_cache).expect("Failed to create resource cache folder");
Ok(ResCache::new(
paths::RES_CACHE.into(),
(&PARAMETERS.res_cache).into(),
mbf_res_man::default_agent::get_agent(),
))
}

pub fn get_apk_path() -> Result<Option<String>> {
let pm_output = Command::new("pm")
.args(["path", APK_ID])
.args(["path", &PARAMETERS.apk_id])
.output()
.context("Working out APK path")?;
if 8 > pm_output.stdout.len() {
Expand Down Expand Up @@ -153,6 +151,9 @@ fn main() -> Result<()> {
reader.read_line(&mut line)?;
let req: request::Request = serde_json::from_str(&line)?;

// Set the parameters for this instance of the agent
init_parameters(&req.agent_parameters.game_id, req.agent_parameters.ignore_package_id);

// Set a panic hook that writes the panic as a JSON Log
// (we don't do this in catch_unwind as we get an `Any` there, which doesn't implement Display)
panic::set_hook(Box::new(|info| {
Expand Down
20 changes: 10 additions & 10 deletions mbf-agent/src/mod_man/loaded_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use std::{collections::HashSet, ffi::{OsStr, OsString}, path::{Path, PathBuf}};

use crate::paths;
use crate::parameters::PARAMETERS;

use super::{util, ModInfo};
use anyhow::{Result, Context};
Expand Down Expand Up @@ -84,17 +84,17 @@ impl Mod {
util::copy_files_from_mod_folder(
&self.loaded_from,
&self.manifest().mod_files,
paths::EARLY_MODS,
&PARAMETERS.early_mods,
)?;
util::copy_files_from_mod_folder(
&self.loaded_from,
&self.manifest().library_files,
paths::LIBS,
&PARAMETERS.libs,
)?;
util::copy_files_from_mod_folder(
&self.loaded_from,
&self.manifest().late_mod_files,
paths::LATE_MODS,
&PARAMETERS.late_mods,
)?;

self.copy_file_copies().context("Copying auxillary files")?;
Expand All @@ -114,11 +114,11 @@ impl Mod {
// Delete all mod binary files.
util::remove_file_names_from_folder(
self.manifest().mod_files.iter(),
paths::EARLY_MODS,
&PARAMETERS.early_mods,
)?;
util::remove_file_names_from_folder(
self.manifest().late_mod_files.iter(),
paths::LATE_MODS,
&PARAMETERS.late_mods,
)?;
util::remove_file_names_from_folder(
// Only delete libraries not in use (!)
Expand All @@ -127,7 +127,7 @@ impl Mod {
.library_files
.iter()
.filter(|lib_file| !retained_libs.contains(OsStr::new(lib_file))),
paths::LIBS,
&PARAMETERS.libs,
)?;

// Delete all file copies.
Expand Down Expand Up @@ -198,9 +198,9 @@ impl Mod {
/// destinations.
fn check_if_files_copied(manifest: &ModInfo) -> Result<bool> {
Ok(
util::files_exist_in_dir(paths::EARLY_MODS, manifest.mod_files.iter())?
&& util::files_exist_in_dir(paths::LATE_MODS, manifest.late_mod_files.iter())?
&& util::files_exist_in_dir(paths::LIBS, manifest.library_files.iter())?
util::files_exist_in_dir(&PARAMETERS.early_mods, manifest.mod_files.iter())?
&& util::files_exist_in_dir(&PARAMETERS.late_mods, manifest.late_mod_files.iter())?
&& util::files_exist_in_dir(&PARAMETERS.libs, manifest.library_files.iter())?
&& manifest
.file_copies
.iter()
Expand Down
26 changes: 13 additions & 13 deletions mbf-agent/src/mod_man/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use mbf_res_man::{
use mbf_zip::ZipFile;
use semver::Version;

use crate::{downloads, paths};
use crate::{downloads, parameters::PARAMETERS};

/// The JSON schema for the `mod.json` file within a qmod.
/// This is the same schema used by QuestPatcher.
Expand Down Expand Up @@ -76,7 +76,7 @@ impl<'cache> ModManager<'cache> {
)
.expect("QMOD schema should be a valid JSON schema"),
// Each game version stores its QMODs in a different directory.
qmods_dir: paths::QMODS.replace('$', &game_version),
qmods_dir: (&PARAMETERS.qmods).replace('$', &game_version),
game_version,
res_cache,
mod_repo: None,
Expand All @@ -89,10 +89,10 @@ impl<'cache> ModManager<'cache> {

// Wipe all mod directories, if they exist.
let to_remove = [
paths::OLD_QMODS,
paths::LATE_MODS,
paths::EARLY_MODS,
paths::LIBS,
&PARAMETERS.old_qmods,
&PARAMETERS.late_mods,
&PARAMETERS.early_mods,
&PARAMETERS.libs,
&self.qmods_dir,
];
for path in to_remove {
Expand Down Expand Up @@ -450,14 +450,14 @@ impl<'cache> ModManager<'cache> {
/// Will do nothing if the old mods directory does not exist.
/// Returns true if any old QMODs were found
fn load_old_qmods(&mut self) -> Result<bool> {
if !Path::new(paths::OLD_QMODS).exists() {
if !Path::new(&PARAMETERS.old_qmods).exists() {
return Ok(false);
}

warn!("Migrating mods from legacy folder");
let mut found_qmod = false;
for stat_result in
std::fs::read_dir(paths::OLD_QMODS).context("Reading old QMODs directory")?
std::fs::read_dir(&PARAMETERS.old_qmods).context("Reading old QMODs directory")?
{
let stat = stat_result?;

Expand All @@ -474,7 +474,7 @@ impl<'cache> ModManager<'cache> {
found_qmod = true;
std::fs::remove_file(stat.path()).context("Deleting legacy mod")?;
}
std::fs::remove_dir(paths::OLD_QMODS)?;
std::fs::remove_dir(&PARAMETERS.old_qmods)?;

Ok(found_qmod)
}
Expand Down Expand Up @@ -741,13 +741,13 @@ impl<'cache> ModManager<'cache> {
/// and the Packages directory that stores the extracted QMODs for the current game version.
fn create_mods_dir(&self) -> Result<()> {
std::fs::create_dir_all(&self.qmods_dir)?;
std::fs::create_dir_all(paths::LATE_MODS)?;
std::fs::create_dir_all(paths::EARLY_MODS)?;
std::fs::create_dir_all(paths::LIBS)?;
std::fs::create_dir_all(&PARAMETERS.late_mods)?;
std::fs::create_dir_all(&PARAMETERS.early_mods)?;
std::fs::create_dir_all(&PARAMETERS.libs)?;
OpenOptions::new()
.create(true)
.write(true)
.open(paths::MODDATA_NOMEDIA)
.open(&PARAMETERS.moddata_nomedia)
.context("Creating nomedia file")?;

Ok(())
Expand Down
Loading