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.1.1.tar.gz (33.4 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.1.1-cp310-abi3-win_amd64.whl (267.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

fs_sav-0.1.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (334.4 kB view details)

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

fs_sav-0.1.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (326.6 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fs_sav-0.1.1-cp310-abi3-macosx_11_0_arm64.whl (316.0 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fs_sav-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl (325.2 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for fs_sav-0.1.1.tar.gz
Algorithm Hash digest
SHA256 02f8e90f938a372a04d8a00056d80117c859803a74ac41db12dffb5ecffe34de
MD5 0b24de0afc5e74a52cb778afced31630
BLAKE2b-256 9cb0c506fec39861b8e9be5cdd494f7c44d53da1cd93f349d7002df6484ea93a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fs_sav-0.1.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 267.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.1.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7c8bf30e8e1b0736b529543b28e1c2ab4a19270066e36d99e731179d6309de4f
MD5 a5ad8c90955709ac513de44f2243bdd5
BLAKE2b-256 9e2a913aad86bfb17e77de906d8ef85d89808146adfb27f457416842980854cc

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.1.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 60e9f66d49d9863b373238e161635d7caa29c0acd5a5714f91d679854f4d08ff
MD5 16deda653925d00777271e66e06d3d26
BLAKE2b-256 04c414c39e6877d77c84f6155b7fc82e0f6bb2ad2fb0459311d49246305c372f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.1.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3a17ba663e6081a5c2486d2490f09cb559794ad7b6b8640ccbfea369d211a9f6
MD5 f1ad7e2385083df05e9ca007fb86bf8e
BLAKE2b-256 c0ac9e0179e89bde187f0011bb3323e32236557bb541fe0f467fe5c9108a5652

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.1.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f2ec211d35f0a44d6ecaa1e639756738287b04ba5b413a501123fdda7582d794
MD5 6b8bfcd8c6c42b1beae240d314465c42
BLAKE2b-256 8f2c4642ee0cf4b5a5c142018b089a70cc4316905c8a17629abaa2b0083f1cce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.1.1-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9fe5556afc238d8bf54f408cfdf649604bc37d968ebdb69dc59527b02256d80f
MD5 95881e08e5a99a28f67e8022137df6ed
BLAKE2b-256 93dc5b2facbb983dc4aef569e57c9cfdbc53b6302af97a24b59f2f47c1b363c1

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