Metadata-Version: 2.4
Name: fsd9lib
Version: 0.1.0
Summary: A Python FSD (Flight Simulator Data) protocol v9 library for VATSIM-compatible pilot client connections
Author: fsd9lib contributors
License-Expression: AGPL-3.0
Project-URL: Homepage, https://github.com/example/fsd9
Project-URL: Repository, https://github.com/example/fsd9
Keywords: fsd,flight-simulator,vatsim,fsd9,fsd9lib,aviation,atc,pilot,flight-simulation,networking,protocol
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Games/Entertainment :: Simulation
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Dynamic: license-file

# fsd9lib

A Python library for the FSD (Flight Simulator Data) protocol version 9 — the classic VATSIM-compatible protocol for flight simulation networking.

**Zero dependencies** — uses only Python's standard library (`asyncio`).

## Features

- Full FSD protocol v9 packet construction and parsing
- PBH (Pitch/Bank/Heading) encoding/decoding
- Radio frequency encoding/decoding
- Async TCP connection with auto-reconnect
- High-level `PilotClient` for crew (pilot) connections
- Callback-based message/position/error handling
- Complete enum types: ratings, facility types, simulator types, error codes, etc.

## Installation

```bash
pip install fsd9lib
```

## Quick Start

```python
import asyncio
from fsd9 import PilotClient, NetworkRating, SimulatorType

async def main():
    # Create a pilot client
    client = PilotClient(
        callsign="N7938C",
        cid="123456",
        password="your_vatsim_password",
        server="eu.velocity.vatsim.net",
        real_name="John Doe",
        sim_type=SimulatorType.MSFS2020,
    )

    # Register callbacks
    async def on_message(client, sender, text):
        print(f"[{sender}] {text}")

    async def on_position(client, callsign, data):
        print(f"  {callsign} @ {data['lat']:.4f}, {data['lon']:.4f} "
              f"FL{data['altitude_true'] // 100} "
              f"GS={data['ground_speed']}kt "
              f"HDG={data['heading']:.0f}°")

    client.on_message = on_message
    client.on_position = on_position

    # Connect and login
    await client.connect()
    print(f"Connected as {client.callsign}")

    # File a flight plan
    await client.file_flight_plan(
        flight_rules="I",
        equipment="H/B738/L",
        tas=450,
        dep_airport="KLAX",
        dest_airport="KSFO",
        cruise_alt=35000,
        hrs_enroute=1,
        min_enroute=30,
        route="VTU5 RZS STOKD SERFR SERFR3",
    )

    # Send position updates
    await client.send_position(40.65906, -73.79891, 35000, 450, 2.0, 0.0, 90.0)

    # Send a text message on frequency
    await client.send_radio_message(122.800, "Traffic in sight")

    # Keep running
    await asyncio.sleep(60)
    await client.disconnect()

asyncio.run(main())
```

## Auto-Position Mode

```python
client = PilotClient(
    callsign="N7938C",
    cid="123456",
    password="secret",
    auto_position=True,     # Automatically send position every 5s
    position_interval=5.0,  # Customize interval
)

await client.connect()

# Set the position once — it will repeat automatically
await client.send_position(40.659, -73.798, 35000, 450)
```

## Low-Level Packet API

Build and parse individual packets without a connection:

```python
from fsd9 import packet, frequency, pbh

# Pack PBH
pbh_val = pbh.pack(pitch=2.0, bank=0.0, heading=90.0)
pitch, bank, heading, on_ground = pbh.unpack(pbh_val)

# Encode frequency
wire = frequency.encode(122.800)  # → 22800
mhz = frequency.decode(22800)     # → 122.800

# Build packets
login = packet.build_add_pilot("N7938C", "123456", "pass")
pos = packet.build_pilot_position("N7938C", "N", 0o2000,
    NetworkRating.OBS, 40.659, -73.798, 35000, 450, 2.0, 0.0, 90.0)
```

## Protocol Version

This library implements **FSD protocol revision 9** (classic/legacy), which uses plaintext password authentication. It does NOT support:
- VATSIM Auth (revision 100) — challenge-response MD5
- VATSIM JWT (revision 101) — JWT tokens
- VATSIM Velocity fast positions (revision 101+)

## License

AGPL-3.0
