System overview
Core components
Proxy server (proxy.py)
The main entry point that orchestrates all other components.
Key responsibilities:
- Accept incoming client connections
- Establish connections to the YSFlight server
- Manage bidirectional packet forwarding
- Coordinate plugin execution
- Handle graceful shutdown and cleanup
proxy.py:369-376
Connection handler
Each client connection runs in its own async task with two forwarding coroutines:- Client → Server: Intercepts outgoing packets from the game client
- Server → Client: Intercepts incoming packets from the game server
proxy.py:301-312
Using
asyncio.FIRST_COMPLETED ensures that when one side disconnects, the entire connection is cleaned up promptly.PacketManager
Centralized packet identification and parsing system. Features:- Maps packet IDs to type names
- Provides packet-specific decoder classes
- Supports 50+ YSFlight packet types
lib/PacketManager/PacketManager.py:5-14
Each packet type has a dedicated class (e.g., FSNETCMD_LOGON, FSNETCMD_AIRPLANESTATE) that handles encoding and decoding.
Player class (lib/Player.py)
Tracks per-connection state and player information.
Attributes:
username- Player’s display namealias- Extended username (for names > 16 chars)version- YSFlight version numberip- Client IP addressaircraft- Current aircraft state (see Aircraft class)iff- Identify Friend or Foe teamis_a_bot- Whether connection is a real playerstreamWriterObject- Socket writer for sending messages
lib/Player.py:3-16
Aircraft class (lib/Aircraft.py)
Tracks the state of a player’s aircraft in real-time.
Tracked data:
- Position (x, y, z coordinates)
- Attitude (heading, pitch, bank)
- Life/health percentage
- Fuel and payload
- Configuration (afterburner, landing gear, flaps, etc.)
- Last received state packet
lib/Aircraft.py:5-18
The
prev_life field enables anti-cheat detection by comparing health between consecutive state updates.Plugin system
Provides extensibility through event hooks. Hook types:on_login- Player connectson_join- Player spawns aircrafton_chat- Player sends messageon_flight_data- Aircraft state updateon_weapon_config- Weapon loadout change- Per-packet hooks for any packet type
proxy.py:234
Plugins can inspect packets, modify game state, and return False to block packet forwarding.
Data flow
Client to server packets
Server to client packets
The flow is identical but reversed:- Server sends packet
- Proxy intercepts and identifies type
- Packet decoded and processed
- State updated (e.g.,
FSNETCMD_ADDOBJECTcreates aircraft) - Hooks triggered
- Forwarded to client (or blocked/modified)
Message queues
Sakuya AC uses two lists to inject custom packets:proxy.py:116-121
Global state
- Broadcasting messages to all players
- Checking for duplicate usernames
- Tracking total player count
- Cross-player interactions
Configuration
Key settings fromconfig.py:
SERVER_HOST- YSFlight server addressSERVER_PORT- YSFlight server portPROXY_PORT- Port for clients to connect toYSF_VERSION- Expected YSFlight versionVIA_VERSION- Enable version translationPREFIX- Command prefix (e.g.,/)DISCORD_ENABLED- Discord integrationLOGGING_LEVEL- Debug verbosity
Concurrency model
Sakuya AC uses Python’sasyncio event loop:
- One task per connection - Isolated, non-blocking
- Two coroutines per task - Bidirectional forwarding
- Non-blocking I/O -
awaiton all socket operations - Task cancellation - Cleanup when connections close
proxy.py:57-62
uvloop is a drop-in replacement for asyncio’s event loop, providing 2-4x better performance on Linux and macOS.