Skip to content

Commit

Permalink
Implement unmodified base game asset lint
Browse files Browse the repository at this point in the history
  • Loading branch information
jieyouxu authored and trumank committed Aug 17, 2023
1 parent 381abb5 commit 29b56c1
Show file tree
Hide file tree
Showing 24 changed files with 291 additions and 45 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ lazy_static = "1.4.0"
modio = { git = "https://github.com/trumank/modio-rs.git", branch = "dev", features = ["rustls-tls"] }
obake = { version = "1.0.5", features = ["serde"] }
opener = "0.6.1"
path-slash = "0.2.1"
rayon = "1.7.0"
regex = "1.9.3"
repak = { git = "https://github.com/trumank/repak.git", version = "0.1.3" }
reqwest = { version = "0.11.18", features = ["blocking"] }
Expand Down
7 changes: 6 additions & 1 deletion src/gui/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ impl LintMods {
store: Arc<ModStore>,
mods: Vec<ModSpecification>,
enabled_lints: BTreeSet<LintId>,
game_pak_path: Option<PathBuf>,
tx: Sender<Message>,
ctx: egui::Context,
) -> MessageHandle<()> {
Expand All @@ -429,7 +430,11 @@ impl LintMods {

let report_res = match mod_path_pairs_res {
Ok(pairs) => tokio::task::spawn_blocking(move || {
crate::mod_lints::run_lints(&enabled_lints, BTreeSet::from_iter(pairs))
crate::mod_lints::run_lints(
&enabled_lints,
BTreeSet::from_iter(pairs),
game_pak_path,
)
})
.await
.unwrap(),
Expand Down
44 changes: 44 additions & 0 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct LintOptions {
shader_files: bool,
non_asset_files: bool,
split_asset_pairs: bool,
unmodified_game_assets: bool,
}

enum LastActionStatus {
Expand Down Expand Up @@ -900,6 +901,16 @@ impl App {
ui.label("Mods containing split {uexp, uasset} pairs");
ui.add(toggle_switch(&mut self.lint_options.split_asset_pairs));
ui.end_row();

ui.label("Mods containing unmodified game assets");
ui.add_enabled(
self.state.config.drg_pak_path.is_some(),
toggle_switch(&mut self.lint_options.unmodified_game_assets),
)
.on_disabled_hover_text(
"This lint requires DRG pak path to be specified",
);
ui.end_row();
});
});

Expand Down Expand Up @@ -942,6 +953,10 @@ impl App {
LintId::SPLIT_ASSET_PAIRS,
self.lint_options.split_asset_pairs,
),
(
LintId::UNMODIFIED_GAME_ASSETS,
self.lint_options.unmodified_game_assets,
),
]);

trace!(?lint_options);
Expand All @@ -956,6 +971,7 @@ impl App {
.into_iter()
.filter_map(|(lint, enabled)| enabled.then_some(lint)),
),
self.state.config.drg_pak_path.clone(),
self.tx.clone(),
ctx.clone(),
));
Expand Down Expand Up @@ -1228,6 +1244,34 @@ impl App {
});
}
}

if let Some(unmodified_game_assets_mods) = &report.unmodified_game_assets_mods {
if !unmodified_game_assets_mods.is_empty() {
CollapsingHeader::new(
RichText::new(
"⚠ Mod(s) with unmodified game assets detected",
)
.color(AMBER),
)
.default_open(true)
.show(ui, |ui| {
unmodified_game_assets_mods.iter().for_each(|(r#mod, files)| {
CollapsingHeader::new(
RichText::new(format!(
"⚠ {} includes unmodified game assets",
r#mod.url
))
.color(AMBER),
)
.show(ui, |ui| {
files.iter().for_each(|file| {
ui.label(file);
});
});
});
});
}
}
});
} else {
ui.spinner();
Expand Down
8 changes: 0 additions & 8 deletions src/gui/toggle_switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

use eframe::egui;

/// Here is the same code again, but a bit more compact:
fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0, 1.0);
let (rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
Expand All @@ -29,13 +28,6 @@ fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
response
}

// A wrapper that allows the more idiomatic usage pattern: `ui.add(toggle(&mut my_bool))`
/// iOS-style toggle switch.
///
/// ## Example:
/// ``` ignore
/// ui.add(toggle(&mut my_bool));
/// ```
#[allow(clippy::needless_pass_by_ref_mut)]
pub fn toggle_switch(on: &mut bool) -> impl egui::Widget + '_ {
move |ui: &mut egui::Ui| toggle_ui(ui, on)
Expand Down
26 changes: 20 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,15 +228,15 @@ fn init_provider(state: &mut State, url: String, factory: &ProviderFactory) -> R
}

async fn action_integrate(action: ActionIntegrate) -> Result<()> {
let path_game_pak = action
let game_pak_path = action
.fsd_pak
.or_else(|| {
DRGInstallation::find()
.as_ref()
.map(DRGInstallation::main_pak)
})
.context("Could not find DRG pak file, please specify manually with the --fsd_pak flag")?;
debug!(?path_game_pak);
debug!(?game_pak_path);

let mut state = State::init()?;

Expand All @@ -247,7 +247,7 @@ async fn action_integrate(action: ActionIntegrate) -> Result<()> {
.collect::<Vec<_>>();

resolve_unordered_and_integrate_with_provider_init(
path_game_pak,
game_pak_path,
&mut state,
&mod_specs,
action.update,
Expand All @@ -257,15 +257,15 @@ async fn action_integrate(action: ActionIntegrate) -> Result<()> {
}

async fn action_integrate_profile(action: ActionIntegrateProfile) -> Result<()> {
let path_game_pak = action
let game_pak_path = action
.fsd_pak
.or_else(|| {
DRGInstallation::find()
.as_ref()
.map(DRGInstallation::main_pak)
})
.context("Could not find DRG pak file, please specify manually with the --fsd_pak flag")?;
debug!(?path_game_pak);
debug!(?game_pak_path);

let mut state = State::init()?;

Expand All @@ -275,7 +275,7 @@ async fn action_integrate_profile(action: ActionIntegrateProfile) -> Result<()>
});

resolve_unordered_and_integrate_with_provider_init(
path_game_pak,
game_pak_path,
&mut state,
&mods,
action.update,
Expand All @@ -285,6 +285,16 @@ async fn action_integrate_profile(action: ActionIntegrateProfile) -> Result<()>
}

async fn action_lint(action: ActionLint) -> Result<()> {
let game_pak_path = action
.fsd_pak
.or_else(|| {
DRGInstallation::find()
.as_ref()
.map(DRGInstallation::main_pak)
})
.context("Could not find DRG pak file, please specify manually with the --fsd_pak flag")?;
debug!(?game_pak_path);

let mut state = State::init()?;

let mut mods = Vec::new();
Expand All @@ -303,8 +313,12 @@ async fn action_lint(action: ActionLint) -> Result<()> {
LintId::EMPTY_ARCHIVE,
LintId::OUTDATED_PAK_VERSION,
LintId::SHADER_FILES,
LintId::ARCHIVE_WITH_MULTIPLE_PAKS,
LintId::NON_ASSET_FILES,
LintId::SPLIT_ASSET_PAIRS,
]),
BTreeSet::from_iter(mods.into_iter().zip(mod_paths)),
Some(game_pak_path),
)
})
.await??;
Expand Down
2 changes: 1 addition & 1 deletion src/mod_lints/archive_multiple_paks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Lint for ArchiveMultiplePaksLint {
fn check_mods(&mut self, lcx: &LintCtxt) -> Result<Self::Output> {
let mut archive_multiple_paks_mods = BTreeSet::new();
lcx.for_each_mod(
|_, _| Ok(()),
|_, _, _| Ok(()),
None::<fn(ModSpecification)>,
None::<fn(ModSpecification)>,
Some(|mod_spec| {
Expand Down
2 changes: 1 addition & 1 deletion src/mod_lints/archive_only_non_pak_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ impl Lint for ArchiveOnlyNonPakFilesLint {
fn check_mods(&mut self, lcx: &LintCtxt) -> anyhow::Result<Self::Output> {
let mut archive_only_non_pak_files_mods = BTreeSet::new();
lcx.for_each_mod(
|_, _| Ok(()),
|_, _, _| Ok(()),
None::<fn(ModSpecification)>,
Some(|mod_spec| {
archive_only_non_pak_files_mods.insert(mod_spec);
Expand Down
2 changes: 1 addition & 1 deletion src/mod_lints/asset_register_bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Lint for AssetRegisterBinLint {
fn check_mods(&mut self, lcx: &LintCtxt) -> Result<Self::Output> {
let mut asset_register_bin_mods = BTreeMap::new();

lcx.for_each_mod_file(|mod_spec, _, raw_path, normalized_path| {
lcx.for_each_mod_file(|mod_spec, _, _, raw_path, normalized_path| {
if let Some(filename) = raw_path.file_name() {
if filename == "AssetRegistry.bin" {
asset_register_bin_mods
Expand Down
2 changes: 1 addition & 1 deletion src/mod_lints/conflicting_mods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Lint for ConflictingModsLint {
fn check_mods(&mut self, lcx: &LintCtxt) -> Result<Self::Output> {
let mut per_path_modifiers = BTreeMap::new();

lcx.for_each_mod_file(|mod_spec, _, _, normalized_path| {
lcx.for_each_mod_file(|mod_spec, _, _, _, normalized_path| {
per_path_modifiers
.entry(normalized_path)
.and_modify(|modifiers: &mut IndexSet<ModSpecification>| {
Expand Down
2 changes: 1 addition & 1 deletion src/mod_lints/empty_archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl Lint for EmptyArchiveLint {
let mut empty_archive_mods = BTreeSet::new();

lcx.for_each_mod(
|_, _| Ok(()),
|_, _, _| Ok(()),
Some(|mod_spec| {
empty_archive_mods.insert(mod_spec);
}),
Expand Down
Loading

0 comments on commit 29b56c1

Please sign in to comment.