valve_pak 0.1.0

A library and CLI tool for reading and writing Valve Pak files
Documentation
# Valve Pak (VPK) - Valve Pak File Library and CLI Tool

A Rust library and command-line tool for reading, writing, and manipulating Valve Pak (VPK) files used by Valve's Source engine games.

## Features

- **Full VPK Format Support**: Both VPK v1 and v2 formats
- **Unified API**: Single struct handles both reading and writing operations
- **Checksum Verification**: MD5 checksum verification for VPK v2 files
- **High Performance**: Efficient I/O with buffered readers/writers and streaming
- **Memory Safe**: Written in Rust with comprehensive error handling
- **CLI Tool**: Complete command-line interface for common operations
- **File-like Access**: VPKFile implements standard Read/Seek traits

## Installation

### From Source

```bash
git clone <repository-url>
cd valve-pak-rs
cargo build --release
```

The compiled binary will be available at `target/release/valve_pak`.

### As a Library

Add to your `Cargo.toml`:

```bash
cargo add valve_pak
```

## CLI Usage

### Pack a directory into a VPK file

```bash
valve_pak pack <directory> <output.vpk> [--verbose]
```

Example:
```bash
valve_pak pack my_mod/ my_mod.vpk --verbose
```

### Unpack a VPK file to a directory

```bash
valve_pak unpack <input.vpk> <output_directory> [--verbose]
```

Example:
```bash
valve_pak unpack game_assets.vpk extracted/ --verbose
```

### List files in a VPK

```bash
valve_pak list <input.vpk> [--detailed]
```

Examples:
```bash
valve_pak list game_assets.vpk
valve_pak list game_assets.vpk --detailed  # Shows file sizes and CRC32
```

### Verify VPK checksums and file integrity

```bash
valve_pak verify <input.vpk>
```

Example:
```bash
valve_pak verify game_assets.vpk
```

### Extract a single file from VPK

```bash
valve_pak extract <input.vpk> <file_path> <output_file>
```

Example:
```bash
valve_pak extract game_assets.vpk scripts/game.txt extracted_game.txt
```

## Library Usage

### Basic Operations

```rust
use valve_pak::{VPK, Result};

fn main() -> Result<()> {
    // Open an existing VPK file
    let vpk = VPK::open("game_assets.vpk")?;
    
    // List all files
    for file_path in vpk.file_paths() {
        println!("{}", file_path);
    }
    
    // Get a specific file
    let mut file = vpk.get_file("scripts/game.txt")?;
    
    // Read file content
    let content = file.read_all_string()?;
    println!("File content: {}", content);
    
    // Save file to disk
    file.save("extracted_game.txt")?;
    
    Ok(())
}
```

### Creating VPK files

```rust
use valve_pak::{VPK, Result};

fn main() -> Result<()> {
    // Create VPK from directory
    let vpk = VPK::from_directory("my_mod/")?;
    
    // Save to file
    vpk.save("my_mod.vpk")?;
    
    println!("Packed {} files", vpk.file_count());
    Ok(())
}
```

### File Operations

```rust
use valve_pak::{VPK, Result};
use std::io::{Read, Seek, SeekFrom};

fn main() -> Result<()> {
    let vpk = VPK::open("game_assets.vpk")?;
    let mut file = vpk.get_file("textures/logo.png")?;
    
    // VPKFile implements Read and Seek traits
    let mut buffer = [0u8; 1024];
    let bytes_read = file.read(&mut buffer)?;
    
    // Seek to position
    file.seek(SeekFrom::Start(100))?;
    
    // Verify file integrity
    if file.verify()? {
        println!("File checksum is valid");
    }
    
    Ok(())
}
```

### Error Handling

```rust
use valve_pak::{VPK, Result};

fn main() -> Result<()> {
    match VPK::open("nonexistent.vpk") {
        Ok(vpk) => {
            println!("Opened VPK with {} files", vpk.file_count());
        }
        Err(e) => {
            eprintln!("Failed to open VPK: {}", e);
            // Error context is preserved through the chain
            for cause in e.chain() {
                eprintln!("  Caused by: {}", cause);
            }
        }
    }
    Ok(())
}
```

## VPK Format Support

### Version 1 (V1)
- Basic file tree structure
- CRC32 checksums for individual files
- No global checksums

### Version 2 (V2)
- Extended header with metadata
- MD5 checksums for entire archive
- Support for chunk hashes
- Backward compatible with V1

## Performance

The library is optimized for performance:

- **Streaming I/O**: Uses buffered readers/writers for efficient file operations
- **Lazy Loading**: File tree is loaded on demand when needed
- **Memory Efficient**: Large files are streamed rather than loaded entirely into memory
- **Zero-Copy**: Minimal data copying during read operations

## Error Handling

All operations return `Result<T>` types with descriptive error messages using the `anyhow` crate. Errors include full context chains to help with debugging.

## Testing

Run the test suite:

```bash
cargo test
```

Run tests with output:

```bash
cargo test -- --nocapture
```

## Dependencies

- `anyhow` - Error handling with context
- `clap` - Command line argument parsing
- `md5` - MD5 checksum calculation (VPK v2)
- `crc32fast` - Fast CRC32 calculation
- `walkdir` - Recursive directory traversal

## License

MIT License - see LICENSE file for details.

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Submit a pull request