added local overrides in instance
This commit is contained in:
@@ -170,6 +170,9 @@ pub struct ModdedInstance {
|
|||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub load_order: Vec<String>,
|
pub load_order: Vec<String>,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
game_file_overrides: Vec<Link>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModdedInstance {
|
impl ModdedInstance {
|
||||||
@@ -178,6 +181,7 @@ impl ModdedInstance {
|
|||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
mods: Vec::new(),
|
mods: Vec::new(),
|
||||||
load_order: Vec::new(),
|
load_order: Vec::new(),
|
||||||
|
game_file_overrides: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +256,10 @@ impl ModdedInstance {
|
|||||||
pub fn load_order(&self) -> &[String] {
|
pub fn load_order(&self) -> &[String] {
|
||||||
&self.load_order
|
&self.load_order
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn game_file_overrides(&self) -> &[Link] {
|
||||||
|
&self.game_file_overrides
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
use log::debug;
|
use log::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::basic_types::{Game, Link, ModdedInstance, RootConfig};
|
||||||
basic_types::{Game, Link, ModdedInstance, RootConfig},
|
|
||||||
utils::walk_files_recursive,
|
|
||||||
};
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::{fs, io, os::unix, path::Path};
|
use std::{fs, io, os::unix, path::Path};
|
||||||
|
|
||||||
@@ -27,12 +24,11 @@ pub fn link_instance_to_target(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_game_to_target(game: &Game, target: impl AsRef<Path>) -> Result<(), io::Error> {
|
pub fn apply_link(link: &Link, target: impl AsRef<Path>) -> Result<(), io::Error> {
|
||||||
for link in game.export_links()? {
|
let link_target = &link.src;
|
||||||
link_file(&link.src, &target.as_ref().join(&link.dst))?;
|
let link_name = target.as_ref().join(&link.dst);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
link_file(&link_target, &link_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link_file(target: &Path, link_name: &Path) -> Result<(), io::Error> {
|
fn link_file(target: &Path, link_name: &Path) -> Result<(), io::Error> {
|
||||||
|
|||||||
56
src/main.rs
56
src/main.rs
@@ -2,14 +2,15 @@ use clap::Parser;
|
|||||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
error::Error,
|
error::Error,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
basic_types::{ModConfig, ModFile, ModdedInstance, RootConfig},
|
basic_types::{Game, Link, ModConfig, ModFile, ModdedInstance, RootConfig},
|
||||||
cli::Args,
|
cli::Args,
|
||||||
linker::{create_plugins_txt, link_game_to_target, link_instance_to_target},
|
linker::{apply_link, create_plugins_txt},
|
||||||
load_order::LoadOrder,
|
load_order::LoadOrder,
|
||||||
mod_config_installer::FomodInstaller,
|
mod_config_installer::FomodInstaller,
|
||||||
utils::{resolve_case_insensitive, walk_files_recursive},
|
utils::{resolve_case_insensitive, walk_files_recursive},
|
||||||
@@ -150,13 +151,60 @@ pub fn activate_instance(
|
|||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let instance_config = root_config.load_instance_by_id(instance_id)?;
|
let instance_config = root_config.load_instance_by_id(instance_id)?;
|
||||||
|
|
||||||
link_game_to_target(root_config.games.first().unwrap(), target)?;
|
let links = gen_links_for_activation(
|
||||||
link_instance_to_target(root_config, &instance_config, target)?;
|
root_config,
|
||||||
|
&instance_config,
|
||||||
|
root_config.games.first().unwrap(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
links.iter().try_for_each(|link| apply_link(link, target));
|
||||||
create_plugins_txt(&instance_config, target)?;
|
create_plugins_txt(&instance_config, target)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gen_links_for_activation(
|
||||||
|
root_config: &RootConfig,
|
||||||
|
instance: &ModdedInstance,
|
||||||
|
game: &Game,
|
||||||
|
) -> Result<Vec<Link>, Box<dyn Error>> {
|
||||||
|
let game_links = game.export_links()?;
|
||||||
|
let mod_links = gen_links_for_instance(root_config, instance)?;
|
||||||
|
let overrides = instance.game_file_overrides().to_owned();
|
||||||
|
|
||||||
|
let mut map: HashMap<PathBuf, PathBuf> = HashMap::new();
|
||||||
|
|
||||||
|
for link in game_links.into_iter().chain(mod_links).chain(overrides) {
|
||||||
|
map.insert(link.dst, link.src);
|
||||||
|
}
|
||||||
|
|
||||||
|
let final_links: Vec<Link> = map
|
||||||
|
.into_iter()
|
||||||
|
.map(|(dst, src)| Link::new(src, dst))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(final_links)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gen_links_for_instance(
|
||||||
|
root_config: &RootConfig,
|
||||||
|
instance: &ModdedInstance,
|
||||||
|
) -> Result<Vec<Link>, Box<dyn Error>> {
|
||||||
|
let mut links: Vec<Link> = Vec::new();
|
||||||
|
|
||||||
|
for installed_mod in &instance.mods {
|
||||||
|
let mod_config = root_config.get_mod_by_id(&installed_mod.mod_id()).unwrap();
|
||||||
|
let mod_source_root = root_config.get_mod_location(&mod_config);
|
||||||
|
|
||||||
|
for link in installed_mod.files() {
|
||||||
|
let link_target = mod_source_root.join(&link.src);
|
||||||
|
links.push(Link::new(link_target, &link.dst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(links)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_mod_to_instance(
|
pub fn add_mod_to_instance(
|
||||||
root_config: &RootConfig,
|
root_config: &RootConfig,
|
||||||
instance_id: &str,
|
instance_id: &str,
|
||||||
|
|||||||
Reference in New Issue
Block a user