Skip to content

Commit

Permalink
Implement split uexp/uasset lint
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu committed Aug 15, 2023
1 parent 23b0add commit 084facb
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 5 deletions.
66 changes: 62 additions & 4 deletions src/mod_lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ use tracing::{info, span, trace, Level};
use crate::providers::ModSpecification;
use crate::{lint_get_all_files_from_data, open_file, GetAllFilesFromDataError, PakOrNotPak};

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum SplitUasset {
MissingUasset,
MissingUexp,
}

#[derive(Debug, Clone)]
pub struct ModLintReport {
pub conflicting_mods: BTreeMap<String, BTreeSet<(ModSpecification, Vec<u8>)>>,
Expand All @@ -19,6 +25,7 @@ pub struct ModLintReport {
pub archive_with_only_non_pak_files_mods: BTreeSet<ModSpecification>,
pub archive_with_multiple_paks_mods: BTreeSet<ModSpecification>,
pub non_asset_file_mods: BTreeMap<ModSpecification, BTreeSet<String>>,
pub split_uasset_uexp_mods: BTreeMap<ModSpecification, BTreeMap<String, SplitUasset>>,
}

pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
Expand All @@ -36,6 +43,8 @@ pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
let mut empty_archive_mods = BTreeSet::new();
let mut archive_with_multiple_paks_mods = BTreeSet::new();
let mut non_asset_file_mods = BTreeMap::new();
let mut path_extensions_map: BTreeMap<String, BTreeSet<String>> = BTreeMap::new();
let mut split_uasset_uexp_mods = BTreeMap::new();

for (mod_spec, mod_pak_path) in mods {
trace!(?mod_spec, ?mod_pak_path);
Expand Down Expand Up @@ -95,10 +104,7 @@ pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
|| lowercase.ends_with("assetregistry.bin")
|| lowercase.ends_with(".ushaderbytecode"))
{
trace!(
"file is not known unreal asset: `{}`",
lowercase
);
trace!("file is not known unreal asset: `{}`", lowercase);
non_asset_file_mods
.entry(mod_spec.clone())
.and_modify(|files: &mut BTreeSet<String>| {
Expand All @@ -107,6 +113,21 @@ pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
.or_insert_with(|| [lowercase.clone()].into());
}

path_extensions_map
.entry(p.clone())
.and_modify(|extensions| {
if let Some(ext) = p.rsplit('.').next() {
extensions.insert(ext.to_string());
}
})
.or_insert_with(|| {
if let Some(ext) = p.rsplit('.').next() {
[ext.to_string()].into()
} else {
BTreeSet::default()
}
});

let mut buf = vec![];
let mut writer = Cursor::new(&mut buf);
pak.read_file(&p, &mut pak_bufs[0].1, &mut writer)?;
Expand Down Expand Up @@ -146,6 +167,42 @@ pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
}
}
}

path_extensions_map
.iter()
.for_each(|(path_without_ext, exts)| {
match (exts.contains("uasset"), exts.contains("uexp")) {
(true, false) => {
split_uasset_uexp_mods
.entry(mod_spec.clone())
.and_modify(
|mismatched_pairs_map: &mut BTreeMap<String, SplitUasset>| {
mismatched_pairs_map
.insert(path_without_ext.clone(), SplitUasset::MissingUexp);
},
)
.or_insert_with(|| {
[(path_without_ext.clone(), SplitUasset::MissingUexp)].into()
});
}
(false, true) => {
split_uasset_uexp_mods
.entry(mod_spec.clone())
.and_modify(
|mismatched_pairs_map: &mut BTreeMap<String, SplitUasset>| {
mismatched_pairs_map.insert(
path_without_ext.clone(),
SplitUasset::MissingUasset,
);
},
)
.or_insert_with(|| {
[(path_without_ext.clone(), SplitUasset::MissingUasset)].into()
});
}
_ => {}
}
});
}

const CONFLICTING_MODS_LINT_WHITELIST: [&str; 1] = ["fsd/content/_interop"];
Expand Down Expand Up @@ -189,5 +246,6 @@ pub fn lint(mods: &[(ModSpecification, PathBuf)]) -> Result<ModLintReport> {
archive_with_only_non_pak_files_mods,
archive_with_multiple_paks_mods,
non_asset_file_mods,
split_uasset_uexp_mods,
})
}
Binary file added test_assets/lints/split_uasset_uexp.pak
Binary file not shown.
Empty file.
Empty file.
34 changes: 33 additions & 1 deletion tests/lint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::PathBuf;
use std::str::FromStr;

use drg_mod_integration::mod_lint::ModLintReport;
use drg_mod_integration::mod_lint::{ModLintReport, SplitUasset};
use drg_mod_integration::providers::ModSpecification;

#[test]
Expand Down Expand Up @@ -215,3 +215,35 @@ pub fn test_lint_non_asset_files() {
Some(&["never_gonna_let_you_down.txt".to_string()].into())
);
}

#[test]
pub fn test_lint_split_uasset_uexp_pairs() {
let base_path = PathBuf::from_str("test_assets/lints/").unwrap();
assert!(base_path.exists());
let split_uasset_uexp_pak_path = base_path.clone().join("split_uasset_uexp.pak");
assert!(split_uasset_uexp_pak_path.exists());

let split_uasset_uexp_spec = ModSpecification {
url: "split_uasset_uexp".to_string(),
};

let mods = vec![(split_uasset_uexp_spec.clone(), split_uasset_uexp_pak_path)];

let ModLintReport {
split_uasset_uexp_mods,
..
} = drg_mod_integration::mod_lint::lint(&mods).unwrap();

println!("{:#?}", split_uasset_uexp_mods);

assert_eq!(
split_uasset_uexp_mods.get(&split_uasset_uexp_spec),
Some(
&[
("missing_uasset/a.uexp".to_string(), SplitUasset::MissingUasset),
("missing_uexp/b.uasset".to_string(), SplitUasset::MissingUexp)
]
.into()
)
);
}

0 comments on commit 084facb

Please sign in to comment.