fixed load_order

This commit is contained in:
2026-03-01 23:18:59 +01:00
parent 50151d30df
commit 8fc5480243
2 changed files with 78 additions and 98 deletions

78
src/load_order.rs Normal file
View File

@@ -0,0 +1,78 @@
use std::{
error::Error,
path::{Path, PathBuf},
};
use libloot::{Game, GameType};
use crate::{
basic_types::{ModdedInstance, RootConfig},
utils::walk_files_recursive,
};
pub struct LoadOrder {
game: libloot::Game,
target: PathBuf,
}
impl LoadOrder {
pub fn new(install_dir: impl AsRef<Path>, game_type: GameType) -> Result<Self, Box<dyn Error>> {
Ok(Self {
game: Game::with_local_path(
game_type,
install_dir.as_ref(),
&install_dir.as_ref().join("appdata"),
)?,
target: install_dir.as_ref().to_owned(),
})
}
pub fn add_plugins_from_instance(
&mut self,
root_config: &RootConfig,
instance: &ModdedInstance,
) -> Result<(), Box<dyn Error>> {
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);
let mod_plugins: Vec<PathBuf> = installed_mod
.files()
.iter()
.filter(|f| Self::is_plugin_file(&f.0))
.map(|(from, _)| mod_source_root.join(from))
.collect();
let refs: Vec<_> = mod_plugins.iter().map(|e| e.as_path()).collect();
self.game.load_plugins(&refs)?;
}
Ok(())
}
pub fn add_plugins_from_install(&mut self) -> Result<(), Box<dyn Error>> {
let plugins: Vec<_> = walk_files_recursive(self.target.join("Data"))?
.filter(|f| Self::is_plugin_file(f.path()))
.map(|f| f.path())
.collect();
let refs: Vec<_> = plugins.iter().map(|e| e.as_path()).collect();
dbg!(&refs);
self.game.load_plugins(&refs)?;
Ok(())
}
fn is_plugin_file(filename: impl AsRef<Path>) -> bool {
filename
.as_ref()
.extension()
.is_some_and(|ext| ext == "esp" || ext == "esm" || ext == "esl")
}
pub fn load_order(&self) -> Result<Vec<String>, Box<dyn Error>> {
let all_plugins = self.game.loaded_plugins();
let plugins_names: Vec<&str> = all_plugins.iter().map(|e| e.name()).collect();
let sorted = self.game.sort_plugins(&plugins_names)?;
Ok(sorted)
}
}

View File

@@ -1,98 +0,0 @@
use std::{
fmt::Display,
fs,
path::{Path, PathBuf},
};
use libloot::{
Game, GameType,
error::{GameHandleCreationError, LoadPluginsError, SortPluginsError},
};
use crate::{Mod, ModFile};
pub struct LootOrder {
game: libloot::Game,
target: PathBuf,
}
impl LootOrder {
pub fn new(install_dir: &Path, game_type: GameType) -> Result<Self, LootOrderError> {
Ok(Self {
game: Game::with_local_path(game_type, install_dir, &install_dir.join("appdata"))?,
target: install_dir.to_owned(),
})
}
pub fn add_plugin(&mut self, file: &ModFile) -> Result<(), LootOrderError> {
if !Self::is_plugin_file(file.dest.to_str().unwrap_or_default()) {
return Ok(());
}
let rel_path = self.target.join(&file.dest);
let absolute_path = fs::canonicalize(rel_path).unwrap();
self.game.load_plugins(&[&absolute_path])?;
Ok(())
}
fn is_plugin_file(filename: &str) -> bool {
filename.ends_with(".esp") || filename.ends_with(".esm") || filename.ends_with(".esl")
}
pub fn load_order(&self) -> Result<(), LootOrderError> {
let all_plugins = self.game.loaded_plugins();
let plugins_names: Vec<&str> = all_plugins.iter().map(|e| e.name()).collect();
let sorted = self.game.sort_plugins(&plugins_names)?;
dbg!(sorted);
todo!()
}
}
#[derive(Debug)]
pub enum LootOrderError {
Create(GameHandleCreationError),
Load(LoadPluginsError),
Sort(SortPluginsError),
}
impl std::error::Error for LootOrderError {}
impl Display for LootOrderError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LootOrderError::Create(game_handle_creation_error) => write!(
f,
"Failed to create LootOrder: {}",
game_handle_creation_error
),
LootOrderError::Load(load_plugins_error) => {
write!(f, "Failed to load plugin: {}", load_plugins_error)
}
LootOrderError::Sort(sort_plugins_error) => {
write!(f, "Failed to sort: {}", sort_plugins_error)
}
}
}
}
impl From<GameHandleCreationError> for LootOrderError {
fn from(e: GameHandleCreationError) -> Self {
Self::Create(e)
}
}
impl From<LoadPluginsError> for LootOrderError {
fn from(e: LoadPluginsError) -> Self {
Self::Load(e)
}
}
impl From<SortPluginsError> for LootOrderError {
fn from(e: SortPluginsError) -> Self {
Self::Sort(e)
}
}