use std::mem::forget;
use std::path::PathBuf;
use anyhow::{bail, Result};
use clap::Parser;
use tiger_lib::{
disable_ansi_colors, emit_reports, find_game_directory_steam, set_show_loaded_mods,
set_show_vanilla, validate_config_file, Everything, Game, ModFile,
};
const CK3_APP_ID: &str = "1158310";
const CK3_DIR: &str = "steamapps/common/Crusader Kings III";
const CK3_SIGNATURE_FILE: &str = "game/events/witch_events.txt";
#[derive(Parser)]
struct Cli {
modpath: PathBuf,
#[clap(long)]
ck3: Option<PathBuf>,
#[clap(long)]
config: Option<PathBuf>,
#[clap(long)]
show_vanilla: bool,
#[clap(long)]
show_mods: bool,
#[clap(long)]
json: bool,
#[clap(long)]
unused: bool,
#[clap(long)]
pod: bool,
#[clap(long)]
no_color: bool,
}
fn main() -> Result<()> {
let mut args = Cli::parse();
#[cfg(windows)]
if !args.no_color {
let _ = ansiterm::enable_ansi_support()
.map_err(|_| eprintln!("Failed to enable ANSI support for Windows10 users. Continuing probably without colored output."));
}
eprintln!("This validator was made for Crusader Kings version 1.12.1 (Scythe).");
eprintln!("If you are using a newer version of Crusader Kings, it may be inaccurate.");
eprintln!("!! Currently it's inaccurate anyway because it's in beta state.");
Game::set(Game::Ck3)?;
if args.ck3.is_none() {
args.ck3 = find_game_directory_steam(CK3_APP_ID, &PathBuf::from(CK3_DIR));
}
if let Some(ref mut ck3) = args.ck3 {
eprintln!("Using CK3 directory: {}", ck3.display());
let mut sig = ck3.clone();
sig.push(CK3_SIGNATURE_FILE);
if !sig.is_file() {
eprintln!("That does not look like a CK3 directory.");
ck3.push("..");
eprintln!("Trying: {}", ck3.display());
sig = ck3.clone();
sig.push(CK3_SIGNATURE_FILE);
if sig.is_file() {
eprintln!("Ok.");
} else {
bail!("Cannot find CK3 directory. Please supply it as the --ck3 option.");
}
}
} else {
bail!("Cannot find CK3 directory. Please supply it as the --ck3 option.");
}
args.config = validate_config_file(args.config);
if args.show_vanilla {
eprintln!("Showing warnings for base game files too. There will be many false positives in those.");
}
if args.show_mods {
eprintln!("Showing warnings for other loaded mods too.");
}
if args.unused {
eprintln!("Showing warnings for unused localization. There will be many false positives.");
}
if args.pod {
eprintln!("Doing special checks for the Princes of Darkness mod.");
}
if args.modpath.is_dir() {
args.modpath.push("descriptor.mod");
}
if args.no_color {
disable_ansi_colors();
}
let modfile = ModFile::read(&args.modpath)?;
let modpath = modfile.modpath();
if !modpath.exists() {
eprintln!("Looking for mod in {}", modpath.display());
bail!("Cannot find mod directory. Please make sure the .mod file is correct.");
}
eprintln!("Using mod directory: {}", modpath.display());
let mut everything = Everything::new(
args.config.as_deref(),
args.ck3.as_deref(),
&modpath,
modfile.replace_paths(),
)?;
eprintln!();
everything.load_output_settings(true);
everything.load_config_filtering_rules();
if !args.json {
emit_reports(false);
}
if args.no_color {
disable_ansi_colors();
}
if args.show_vanilla {
set_show_vanilla(true);
}
if args.show_mods {
set_show_loaded_mods(true);
}
everything.load_all();
everything.validate_all();
everything.check_rivers();
if args.pod {
everything.check_pod();
}
emit_reports(args.json);
if args.unused {
everything.check_unused();
}
forget(everything);
Ok(())
}