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.1.tar.gz (36.1 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.1-cp310-abi3-win_amd64.whl (650.6 kB view details)

Uploaded CPython 3.10+Windows x86-64

fs_sav-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (702.2 kB view details)

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

fs_sav-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (676.7 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

fs_sav-0.2.1-cp310-abi3-macosx_11_0_arm64.whl (613.7 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

fs_sav-0.2.1-cp310-abi3-macosx_10_12_x86_64.whl (636.6 kB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for fs_sav-0.2.1.tar.gz
Algorithm Hash digest
SHA256 cd34f12413d24c99aeaf93aabff371c2074fb7a04e899b1d8a1bde81956bddaf
MD5 4d84341df925e636ffabcf834a0b894b
BLAKE2b-256 1da1e0486bbd1cb8ed77781f6ac1e611139fbaa1e279acefda6939344d3e6f81

See more details on using hashes here.

File details

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

File metadata

  • Download URL: fs_sav-0.2.1-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 650.6 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.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 f914de65e4e3764fa67d6794d95597bba5ad62cfccfded380552073e22a76d23
MD5 7bb93f044d038a4fd398029333d1a589
BLAKE2b-256 27d23705dd2aa960515279db32c1d25df0c8b2c54528e63befd8f5503980ac52

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 1a0c5376c7431321224c274f8115c8081458dafd8821b3daba456e1aa02b6b04
MD5 485dddfd5ffe850fd8c7855a5e0046d7
BLAKE2b-256 97698846377f757972210b9dfb3486ff6ba0e9acff65ceb0260b05e6f1fab5f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 867941287da13c4be010a595bcd55c1cb0f9d799e1c101ea75dfcf4265c99f05
MD5 816475202a0a1d1c14f07775ab336f20
BLAKE2b-256 525d96ff640412d7217fb78b453a78b112e4bbe2cdceb2b82c80a10d61764a3e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a40eb11bb86a8b5576e18a0573baad7a72cb5c778790d1834f2940329629b77a
MD5 925dec3ce984bfc81d8c942758586192
BLAKE2b-256 19f6bdb3bec87ba158cb0117c71562aafa56d6c74fac70bf523ffa050314847c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fs_sav-0.2.1-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 f87d9396e02ce414f77086f1c9f2413c32dd39450fabd613ac1a4055e5662f99
MD5 3f9a5886d90f746483c22c76cbb687c4
BLAKE2b-256 d053ef305797aa13853b317d08c031d49d4477312f2cea7028cbbe00d1a4ef12

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