cleanup the code and add README.md

This commit is contained in:
2026-07-09 13:24:49 +03:00
parent 198bce5805
commit 2721ba5759
2 changed files with 43 additions and 10 deletions
+25
View File
@@ -0,0 +1,25 @@
# imploder
This util creates and extracts zip archives with the DCL Implode compression and is used mainly for modding the game MDK 2.
Please note that this util intentionally doesn't add any info on modification date of the files when creating an archive. This is because setting "last_modified" adds a "UT extra field modtime" in addition to the regular "file last modified on (DOS date/time)" field. This means that files in an archive created by this util won't have any modification date written.
Here is some help:
```
Usage: imploder <COMMAND>
Commands:
create Create an archive from a directory: create <directory> <archive>
extract Extract an archive into a directory: extract <archive> <directory>
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
Examples:
imploder create directory/ out.zip
imploder extract archive.zip directory/
please note that for `create` the directory contents are placed at the archive root
```
+18 -10
View File
@@ -1,11 +1,17 @@
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use pklib; use pklib;
use rawzip::{ZipArchiveWriter, time::{Utc, UtcDateTime, ZipDateTime}}; use rawzip::{
ZipArchiveWriter,
time::ZipDateTime,
};
use std::{ use std::{
fs::File, io::{Read, Write}, path::Path, time::{Duration, UNIX_EPOCH}, fs::File,
io::{Read, Write},
path::Path,
time::{Duration, UNIX_EPOCH},
}; };
const AFTER_TEST: &str = "\ const AFTER_TEXT: &str = "\
Examples: Examples:
imploder create directory/ out.zip imploder create directory/ out.zip
imploder extract archive.zip directory/ imploder extract archive.zip directory/
@@ -15,7 +21,7 @@ please note that for `create` the directory contents are placed at the archive r
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None)] #[command(author, version, about, long_about = None)]
#[clap(after_help = AFTER_TEST)] #[clap(after_help = AFTER_TEXT)]
struct Args { struct Args {
#[clap(subcommand)] #[clap(subcommand)]
subcommand: AppSubCommand, subcommand: AppSubCommand,
@@ -64,8 +70,8 @@ fn implode_test(
let dir_heh = std::fs::read_dir(input_dir)?; let dir_heh = std::fs::read_dir(input_dir)?;
for file_path in dir_heh { for file_path in dir_heh {
let shit = file_path.unwrap().path().display().to_string(); let filename = file_path.unwrap().path().display().to_string();
file_list.push(shit); file_list.push(filename);
} }
for mut file in file_list { for mut file in file_list {
@@ -80,10 +86,11 @@ fn implode_test(
.modified()? .modified()?
.duration_since(UNIX_EPOCH)? .duration_since(UNIX_EPOCH)?
.as_secs(); .as_secs();
let mod_time2 = ZipDateTime::from_unix(mod_time_unix.cast_signed()); let mod_time = ZipDateTime::from_unix(mod_time_unix.cast_signed());
print!("imploding {}...", file); print!("imploding {}...", file);
let compressed_size = process_file(&mut archive, &file.as_str(), mod_time2, &buf)?; std::io::stdout().flush()?;
let compressed_size = process_file(&mut archive, file.as_str(), mod_time, &buf)?;
println!("{} -> {} bytes", source_byte_count, compressed_size); println!("{} -> {} bytes", source_byte_count, compressed_size);
} }
@@ -170,7 +177,9 @@ fn explode(input_archive: String, output_dir: String) -> Result<(), Box<dyn std:
let modify_time = entry.last_modified(); let modify_time = entry.last_modified();
let _d = match modify_time { let _d = match modify_time {
rawzip::time::ZipDateTimeKind::Utc(dt) => UNIX_EPOCH + Duration::from_secs(dt.to_unix() as u64), rawzip::time::ZipDateTimeKind::Utc(dt) => {
UNIX_EPOCH + Duration::from_secs(dt.to_unix() as u64)
}
_ => UNIX_EPOCH, _ => UNIX_EPOCH,
}; };
@@ -181,7 +190,6 @@ fn explode(input_archive: String, output_dir: String) -> Result<(), Box<dyn std:
if modify_time.year() > 1980 { if modify_time.year() > 1980 {
file.set_modified(_d)?; file.set_modified(_d)?;
} }
} }
} }