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.3.0.tar.gz (38.5 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.3.0-cp310-abi3-win_amd64.whl (655.6 kB view details)

Uploaded CPython 3.10+Windows x86-64

fs_sav-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (703.0 kB view details)

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

fs_sav-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (675.8 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fs_sav-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (611.0 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fs_sav-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (638.0 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for fs_sav-0.3.0.tar.gz
Algorithm Hash digest
SHA256 ea07f2b86af95725af39b8bca5c17040f57a5e837d96422c1bd49c3ccdc02c53
MD5 2a7e886c07d4532f85a99888c5d35ed8
BLAKE2b-256 b854418e9ddf2794c33b98806239eaf8bc17f787592edab24e2563a127dc6f5b

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for fs_sav-0.3.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 cf84ff17897798e770ddfeaf6c657c9bda8dc980cd830a5f66fb4120834eae70
MD5 ea67879e2d0e18ee17cf2c327bd000dc
BLAKE2b-256 aff48ff13b65bd4e3d00c3e62f1ea18ee2cf220484a815096ad5039dba16d10a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 2de9357ea01438a85681146cfe290c8e67801a20701dcb6e00af48c4bda27da5
MD5 5da9160b256ee44ddc6fee7d283e3f13
BLAKE2b-256 1a4b5dfb0116ad15e97a11f4cd41acbc5146fe1fa5ab40538428758055afab00

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 50ad69f8b85b4fdd33a7ae46293a87a3f68a41e98013b84a0690586229242772
MD5 72716b0b8b5ba3fb5ad375bcdb4248c0
BLAKE2b-256 bf39be61a3c6452d368d2908b395914f722934749300d545b74e74f37535e484

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9752bb6533fb14d4d0a2e012f4093669eb46be03ab5ac4eca19ab93da5e4acb3
MD5 e7c81a48dc75644867d1892b9f9d83d5
BLAKE2b-256 163fadd2a24b6ae61207363d5bfa845a832ce1cf18415982bf5e0d5a2b14d4c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 87d5ca7a732fbccc40236ea28488868ee147dff6a82c210e23a4adc04b1e68a4
MD5 338ded3c1f3ec3bb2cc67832648d2d03
BLAKE2b-256 3fcc119a4be04a495dcb4545d7b8e4e589ba3146ff600a72387439c8d2e2601a

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