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.0.tar.gz (35.6 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.0-cp310-abi3-win_amd64.whl (650.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

fs_sav-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (701.4 kB view details)

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

fs_sav-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (678.0 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fs_sav-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (614.3 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fs_sav-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl (637.0 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for fs_sav-0.2.0.tar.gz
Algorithm Hash digest
SHA256 de01fb1157a3d6fe36a1db86c6a519557e17f739b1b220cd5a5d085f8da75abe
MD5 215182daa5dddf462a26ca185bbade14
BLAKE2b-256 211df9d3727d0396f3d2d427d7fbea2f5be1d7074d7d48c28788c20ca309bf96

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fs_sav-0.2.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 650.3 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.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a8b283b0ba0022a5b056ddb613e96e512484dd67eb2d2cdca85d89d7f2b50f89
MD5 b9d86a1aa1c4ee6295bead8281401108
BLAKE2b-256 25dfb3dcdc3e74af4d233f5a7dec5004925e838846ac4f9ae30edee861d477a2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d8b4754bba9eaf20615d85d88da1402d352dc2ded35247bada848242ccc2014e
MD5 f3dd7129c67dfb1a32dc9c2349dcbb3d
BLAKE2b-256 2209f002f23423237415f46495f9bf0e9118ac8cf242233fe0beb83fd634373a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 81b4833b2a8d715b9261154706eeab52f94aa4150e6df2bd20daa4cca42d81b9
MD5 6a5c5bcbaec8cad7fc061228dddc9077
BLAKE2b-256 904d6f79b05d0c079df0280577180eb634f98db97aab6ad4cd1d73e538dc0002

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e9f959a23d8050b8a64819f47b10ed20cc59655a3c1ec5c3e4f7dd043ca62867
MD5 0dd1318c82fd3b58408bc40dd307f278
BLAKE2b-256 ae325ce0f8e5f81c094823672de0acbedb5ff72a8dd98504185a854bf4198fc5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 be712a0f0571ac76d42a1181a699bd6dfe75b9da8cccd424d9bc345b8d95b331
MD5 b6493da5afa7d4b2722762897b7ef662
BLAKE2b-256 51d9abcd34a242b0b29bd66784fbecea4c9a7c9e4e958b69a1073266701e4d46

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