Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
]

[workspace.package]
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["RitoShark"]

Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<a href="https://github.com/LeagueToolkit/Hematite/releases"><img src="https://img.shields.io/github/v/release/LeagueToolkit/Hematite?style=flat-square&label=release&color=blue" alt="Release"></a>
<img src="https://img.shields.io/badge/rust-2021_edition-orange?style=flat-square" alt="Rust">
<img src="https://img.shields.io/badge/platform-windows-0078D6?style=flat-square" alt="Windows">
<img src="https://img.shields.io/badge/tests-76_passing-brightgreen?style=flat-square" alt="Tests">
<img src="https://img.shields.io/badge/tests-84_passing-brightgreen?style=flat-square" alt="Tests">
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License">
</p>
</p>
Expand All @@ -23,9 +23,12 @@ Fix rules are defined in JSON config, so new fixes can be added without recompil
- **Auto-detect mode** — runs all applicable fixes with zero configuration
- **Config-driven fixes** — add new fix rules via JSON, no code changes needed
- **Full write-back** — modified files are written back to disk (BIN, WAD, Fantome)
- **Batch processing** — process entire directories of skin files at once
- **Batch processing** — drag-and-drop folders, process multiple files with progress tracking
- **Windows CMD optimized** — colored output, ASCII-friendly symbols, proper ANSI support
- **LMDB hash system** — loads 1.8M game hashes in under 1 second
- **Remote config** — fetches latest fix rules from GitHub with offline fallback
- **Check mode** — detect issues without modifying files, shows champion/skin info
- **Verbosity levels** — clean output by default, verbose mode for debugging
- **Security hardened** — ZIP bomb protection, path traversal prevention, size limits
- **Dry-run mode** — preview what would be fixed before modifying files
- **JSON output** — machine-readable results for automation pipelines
Expand Down Expand Up @@ -61,7 +64,10 @@ hematite-cli "skin.fantome" --json > results.json
| **Broken Particles** | Fixes particle texture paths recursively | `--particles` |
| **Champion Data** | Removes outdated champion BIN entries | `--remove-champion-bins` |
| **Audio Files** | Removes BNK files with incompatible Wwise versions | `--remove-bnk` |
| **Animations** | Removes .anm animation files from mod | `--remove-anm` |
| **VFX Shape** | Migrates VFX shape data to 14.1+ format | `--vfx-shape` |
| **Invalid Shaders** | Replaces invalid shader references with closest match | `--fix-shaders` |
| **Unreferenced Entries** | Removes CAD/AnimGraph/GearSkinUpgrade entries | `--validate-entries` |

Use `--all` or pass no flags to apply everything.

Expand All @@ -79,12 +85,13 @@ Use `--all` or pass no flags to apply everything.
hematite-cli [OPTIONS] <INPUT>

Arguments:
<INPUT> File or directory to process
<INPUT> File or directory to process (.bin, .wad.client, .fantome, .zip, or folder)

Options:
-o, --output <PATH> Output path (default: creates .fixed.* next to input)
-a, --all Enable all fixes
--dry-run Show what would be fixed without modifying files
--check Check mode: detect issues without fixing, show skin info
--json JSON output for automation
-v, --verbosity <LEVEL> Verbosity: quiet, normal, verbose, trace [default: normal]
--small-mod Skip fallback assets (for texture-only mods)
Expand All @@ -97,7 +104,10 @@ Fix flags:
--particles Fix broken particle textures
--remove-champion-bins Remove outdated champion data
--remove-bnk Remove incompatible audio files
--remove-anm Remove .anm animation files
--vfx-shape Fix VFX shape format (14.1+)
--fix-shaders Fix invalid shader references
--validate-entries Remove unreferenced entries

-h, --help Print help
-V, --version Print version
Expand Down Expand Up @@ -191,7 +201,7 @@ cargo build --release --bin hematite-cli
### Test

```bash
cargo test --workspace # 76 tests
cargo test --workspace # 84 tests
cargo clippy --workspace # Lint check
cargo fmt --all -- --check # Format check
```
Expand All @@ -201,8 +211,8 @@ cargo fmt --all -- --check # Format check
Releases are automated via GitHub Actions. Push a version tag to trigger:

```bash
git tag v0.2.0
git push origin v0.2.0
git tag v0.3.0
git push origin v0.3.0
# CI: generates changelog (git-cliff) → builds binary → creates GitHub Release
```

Expand Down
38 changes: 36 additions & 2 deletions crates/hematite-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@ use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(name = "hematite-cli")]
#[command(about = "League of Legends custom skin fixer")]
#[command(
long_about = "League of Legends custom skin fixer\n\n\
Automatically detects and fixes common issues in custom skins.\n\
Supports .bin, .wad.client, .fantome, and .zip files.\n\n\
By default, all fixes are applied automatically when no specific flags are provided.\n\
Drag and drop files or folders to process multiple skins at once."
)]
#[command(version)]
pub struct Cli {
/// Input file or directory to process
/// Input file or directory to process (.bin, .wad.client, .fantome, .zip, or folder)
pub input: PathBuf,

/// Output path (default: overwrite input)
Expand Down Expand Up @@ -94,7 +101,12 @@ pub struct Cli {
#[arg(long, help = "Process all skins found in mod (not just primary skin)")]
pub all_skins: bool,

#[arg(short = 'v', long, default_value = "normal", help = "Verbosity level")]
#[arg(
short = 'v',
long,
default_value = "normal",
help = "Verbosity: quiet (errors only), normal (clean output), verbose (debug info), trace (all logs)"
)]
pub verbosity: Verbosity,
}

Expand All @@ -121,6 +133,28 @@ const ALL_FIX_IDS: &[&str] = &[
"entry_validator",
];

/// WAD-level fixes (operate on file lists, not BIN property trees).
const WAD_LEVEL_FIXES: &[&str] = &["bnk_remover", "anm_remover", "dds_to_tex"];

/// Filter out WAD-level fixes from a fix list (for BIN-only processing).
pub fn filter_bin_fixes(fixes: &[String]) -> Vec<String> {
fixes
.iter()
.filter(|f| !WAD_LEVEL_FIXES.contains(&f.as_str()))
.cloned()
.collect()
}

/// Filter to only WAD-level fixes.
#[allow(dead_code)]
pub fn filter_wad_fixes(fixes: &[String]) -> Vec<String> {
fixes
.iter()
.filter(|f| WAD_LEVEL_FIXES.contains(&f.as_str()))
.cloned()
.collect()
}

/// Collect selected fix IDs based on CLI flags.
///
/// If `--all` is set or no flags are passed, returns all fix IDs.
Expand Down
Loading
Loading