Skip to main content

Foxhole save file parser - extracts stockpile data from .sav files

Project description

fs-sav

Foxhole save file parser - extracts stockpile data from .sav files.

Features

  • Parse Foxhole save files (.sav) using the uesave library
  • Extract stockpile information: items, locations, types, quantities
  • Watch files for changes with diff modes (NDJSON output)
  • Filter by hex, stockpile type, public/reserve status
  • Output compatible with foxhole-stockpiles
  • Python bindings via PyO3

Installation

Python (from PyPI)

pip install fs-sav

Rust CLI (from source)

cargo install --path .

Python (from source)

pip install maturin
maturin develop --features python

CLI Usage

Parse command

# Parse a save file
fs-sav parse path/to/War.sav

# Parse with compact output (no pretty printing)
fs-sav parse path/to/War.sav --compact

# Read from stdin
cat War.sav | fs-sav parse

Filter options

# Only public stockpiles (non-reserve)
fs-sav parse War.sav --public

# Only reserve stockpiles
fs-sav parse War.sav --reserves

# Filter by hex
fs-sav parse War.sav --hex TerminusHex

# Filter by stockpile type
fs-sav parse War.sav --type Seaport

# Only stockpiles with items
fs-sav parse War.sav --with-items

# Combine filters
fs-sav parse War.sav --hex TerminusHex --public --with-items

Watch command

# Watch for changes (outputs all stockpiles on each change)
fs-sav watch path/to/War.sav

# Watch with custom poll interval (seconds)
fs-sav watch path/to/War.sav --poll 2.0

# Only output stockpiles that changed (any field)
fs-sav watch path/to/War.sav --diff

# Only output stockpiles where items changed
fs-sav watch path/to/War.sav --diff-items

# Watch with filters
fs-sav watch path/to/War.sav --hex TerminusHex --public

Version

fs-sav version

Python Usage

import fs_sav

# Parse a save file
stockpiles = fs_sav.parse_save("path/to/War.sav")
print(f"Found {len(stockpiles)} stockpiles")

for stockpile in stockpiles:
    print(f"  {stockpile['name']} ({stockpile['type']}): {len(stockpile['items'])} items")

# Parse with filters
seaports = fs_sav.parse_save("War.sav", stockpile_type="Seaport")
reserves = fs_sav.parse_save("War.sav", reserves=True)
terminus_public = fs_sav.parse_save("War.sav", hex="TerminusHex", public=True)

# Parse from bytes
with open("War.sav", "rb") as f:
    data = f.read()
stockpiles = fs_sav.parse_save_bytes(data)

# Get parser info
info = fs_sav.info()
print(f"Implementation: {info['implementation']}, Version: {info['version']}")

Filter parameters

Parameter Type Description
public bool Only public stockpiles (non-reserve)
reserves bool Only reserve stockpiles
hex str Filter by hex name (e.g., "TerminusHex")
stockpile_type str Filter by type (e.g., "Seaport")
with_items bool Only stockpiles with items

Rust Library Usage

use fs_sav::{parse_save, ParseResult};

fn main() -> fs_sav::Result<()> {
    let result = parse_save("path/to/War.sav")?;
    println!("Found {} stockpiles", result.stockpiles.len());

    for stockpile in &result.stockpiles {
        println!("  {} ({:?}): {} items",
            stockpile.name,
            stockpile.stockpile_type,
            stockpile.items.len()
        );
    }

    Ok(())
}

Output Format

The output is a JSON array of stockpiles:

[
  {
    "name": "",
    "type": "Seaport",
    "hex": "TerminusHex",
    "coords": { "x": 0.457, "y": 0.664 },
    "is_reserve": false,
    "items": [
      { "code": "Rifle", "quantity": 100, "crated": false },
      { "code": "RifleAmmo", "quantity": 50, "crated": true }
    ],
    "timestamp": "2024-01-15T10:29:00Z"
  }
]

Stockpile Types

The parser recognizes all Foxhole stockpile types:

Category Types
Bases GarrisonStation, Keep, ForwardBase1, RelicBase1, FortBase (T1-T3), BorderBase, TownBase (T1-T3), FortGarrisonStation
Storage StorageFacility, Seaport, AircraftDepot
Facilities Hospital, Refinery, MaintenanceTunnel, FacilityFactorySmallArms, FacilityModificationCenter, FacilityTransfer (Liquid/Material/Resource), FacilityVehicleFactory (T1-T3)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fs_sav-0.2.5.tar.gz (39.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fs_sav-0.2.5-cp310-abi3-win_amd64.whl (656.8 kB view details)

Uploaded CPython 3.10+Windows x86-64

fs_sav-0.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (707.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

fs_sav-0.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (682.0 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fs_sav-0.2.5-cp310-abi3-macosx_11_0_arm64.whl (621.7 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fs_sav-0.2.5-cp310-abi3-macosx_10_12_x86_64.whl (644.7 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file fs_sav-0.2.5.tar.gz.

File metadata

  • Download URL: fs_sav-0.2.5.tar.gz
  • Upload date:
  • Size: 39.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for fs_sav-0.2.5.tar.gz
Algorithm Hash digest
SHA256 4a5749b76dd6e19e1b0ecfb62e69b52980141f32b5086e8b4bfadc688119e08a
MD5 4c9af3da50d2796f27e4bdfd62fc38d9
BLAKE2b-256 48f1af7ac1c745286f22e91def9fcc3f70c5f68ce905fcc56a3cc3fc953a5f9e

See more details on using hashes here.

File details

Details for the file fs_sav-0.2.5-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: fs_sav-0.2.5-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 656.8 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for fs_sav-0.2.5-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 810b3e113ac317992c36cce97a6f8377889bdc1be8229ae9009dbe835381abd3
MD5 e0c229aca24141b4118a16eee9e5f8c2
BLAKE2b-256 44743d3c3772240c1e3cf96149f813270c170efdde8dc7cf584b848aa61af65f

See more details on using hashes here.

File details

Details for the file fs_sav-0.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fs_sav-0.2.5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b680d532f5041ace3affce3b7228db4f3d8233e3726813d94604a5005a9000c1
MD5 435915bf3e5fbb68c0dddb5b2ff7525c
BLAKE2b-256 fff7aa9caae33bb5e2e6862942762f67df54c5beb006bce1f5200fa1be183394

See more details on using hashes here.

File details

Details for the file fs_sav-0.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for fs_sav-0.2.5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3438a3e082fdd6a8929df3c2f4ef91fa841e1337b4da010d1ecea4d6f5bd6454
MD5 6b77c2adff494154fe3934f79700cced
BLAKE2b-256 671ed671e80f64cbeb2a16acb1df20dbcd3997328a6cc854a4a0345de249cacd

See more details on using hashes here.

File details

Details for the file fs_sav-0.2.5-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fs_sav-0.2.5-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 58d879ea5b326d30883a90251a8dcb51d63f091c72a14ea6e72d91c4f952d81f
MD5 904045a15a5999c6a5db1d5aec567037
BLAKE2b-256 b561b26ba52e05dbd3816af607f57a21c359ea2bb783eb14129b5270316581a3

See more details on using hashes here.

File details

Details for the file fs_sav-0.2.5-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for fs_sav-0.2.5-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 c8051c56d205564d84bb28831c16f8c763fbbf4652b77d8374142458b5a54d1e
MD5 87b6d8ef226381c2babed0ce66394975
BLAKE2b-256 2aaf55c9f05b6a69155ad5266745502985712916245849f12e282a65bb817c39

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page