Skip to main content

Unified SDK for Rocket League save file data extraction, Stats API WebSocket client, tracker.gg stats, process detection, rl log file, input (keyboard/controller), and GUI overlay toolkit.

Project description

Nixwrap

Unified Python SDK for Rocket League: save file data extraction, Stats API WebSocket client, tracker.gg stats, process detection, keyboard/controller input, RL log filem and a reusable GUI/overlay toolkit.

Built because EAC made traditional plugin development for online matches harder. Intended for streamers, tool developers, and anyone who wants RL data in Python.

Installation

From github

pip install git+https://github.com/nixvio64/nixwrap

# With optional extras:
pip install "nixwrap[tracker] @ git+https://github.com/nixvio64/nixwrap"   # tracker.gg
pip install "nixwrap[gui] @ git+https://github.com/nixvio64/nixwrap"       # overlay / GUI
pip install "nixwrap[input] @ git+https://github.com/nixvio64/nixwrap"     # keyboard + controller
pip install "nixwrap[all] @ git+https://github.com/nixvio64/nixwrap"      # everything

From PyPi

pip install nixwrap-rl

# With optional extras:
pip install nixwrap-rl[tracker]   # tracker.gg
pip install nixwrap-rl[gui]       # overlay / GUI
pip install nixwrap-rl[input]     # keyboard + controller
pip install nixwrap-rl[all]       # everything

Modules

Module Purpose Requires
nixwrap.save_file Decrypt + extract data from .save files pycryptodome
nixwrap.process Detect running RL (Steam vs Epic) psutil
nixwrap.stats Live Stats API WebSocket events -
nixwrap.tracker tracker.gg player rank/stats curl-cffi (optional)
nixwrap.input Keyboard, Xbox, DualSense hotkey detection dualsense-controller, keyboard (optional)
nixwrap.gui Overlay/GUI toolkit PySide6 (optional)
nixwrap.log Launch.log parser (session + match info) -
nixwrap.utils Constants, rank helpers, PsyNet config API -

Quick Start

0. Edit your DefaultStatsAPI.ini

Found at <RL Install Dir>\TAGame\Config\DefaultStatsAPI.ini set PacketSendRate value to something like 20 (1-120).

1. Save File Data Extraction

from nixwrap.save_file import load, find_save_file

# Auto-find the active save file
path = find_save_file()
save = load(path)

# Camera
print(save.camera.fov)           # 110.0
print(save.camera.stiffness)     # 0.55

# Controls (keyboard + gamepad)
print(save.controls.jump)                    # "SpaceBar"
print(save.gamepad_bindings.boost)           # "XboxTypeS_RightShoulder"

# Raw bindings for custom inspection
for b in save.gamepad_bindings.raw_bindings:
    print(f"  {b['Action']} -> {b['Key']}")

# Stats
print(save.stats.wins)           # 1234
print(save.xp.level)             # 27
print(save.xp.total_xp)          # 348223

# Skill data per playlist
for pid, skill in save.skills.items():
    print(f"Playlist {pid}: matches={skill.matches_played}, tier={skill.tier}")

# Inventory
for item in save.inventory:
    print(f"Product {item.product_id} (series {item.series_id})")

# Settings
print(save.video.res_width, save.video.res_height)
print(save.gameplay.controller_deadzone)
print(save.sound.master_volume)

# Quick chats, loadout sets, season, achievements, etc.
print(len(save.quick_chats), "quick chat bindings")
print(len(save.loadout_sets), "loadout presets")

raw = load_raw("path/to/savefile.save")
# raw["header"], raw["properties"], raw["objects"]

2. Process Detection

from nixwrap.process import find_rocket_league, is_rocket_league_focused

rl = find_rocket_league()
if rl:
    print(f"PID: {rl.pid}")
    print(f"Platform: {rl.platform.value}")      # steam or epic
    print(f"Root dir: {rl.root_dir}")
    print(f"Save path: {rl.save_data_path}")

if is_rocket_league_focused():
    print("RL window has focus")

3. Input Detection (Keyboard + Controller)

from nixwrap.input import (
    is_hotkey_pressed, is_key_pressed,
    get_xinput_state, XINPUT_A,
    setup_dualsense, start_dualsense_monitor,
    get_button_display,
)

# Keyboard
if is_key_pressed("tab"):
    print("Tab is held")

# XInput (Xbox / DS4 via DS4Windows)
state = get_xinput_state()
if state and state.is_pressed(XINPUT_A):
    print("A button pressed")

# DualSense (PS5)
controller = setup_dualsense()       # auto-finds bundled hidapi.dll
start_dualsense_monitor()            # background auto-reconnect

# Unified hotkey check (InGameRank-compatible config format)
config = {"is_controller": True, "controller_type": "xinput",
          "controller_button": XINPUT_A}
if is_hotkey_pressed(config):
    print("Hotkey held!")

# Button display names
print(get_button_display("xinput", XINPUT_A))           # "A"
print(get_button_display("dualsense", 0))               # "Cross"

4. Stats API (Live Events)

from nixwrap.stats import StatsClient

client = StatsClient()

# Callback mode
client.on("GoalScored", lambda evt: print(f"GOAL! {evt.scorer.name}"))
client.on("StatfeedEvent", lambda evt: print(f"{evt.main_target.name}: {evt.stat_type}"))
client.on_event(lambda evt: print(f"[{evt.event_type}]"))

with client:
    import time
    time.sleep(300)  # listen for 5 minutes

Async mode:

import asyncio
from nixwrap.stats import StatsClient

async def main():
    client = StatsClient()
    client.start()
    async for event in client.events():
        print(event.event_type)
        if event.event_type == "GoalScored":
            print(f"  {event.scorer.name} scored!")

asyncio.run(main())

5. Tracker API (Player Ranks)

from nixwrap.tracker import TrackerClient

client = TrackerClient()  # random browser fingerprint per request
stats = client.fetch("Steam|123456789|0", "PlayerName")

if stats.error:
    print(f"Error: {stats.error}")
else:
    print(f"Last updated: {stats.last_updated}")
    print(f"Lifetime: {stats.lifetime.wins} wins, {stats.lifetime.goals} goals")
    for pid, rank in stats.ranks.items():
        print(f"  {rank.playlist_name}: {rank.tier_name} {rank.division_name} "
              f"({rank.mmr} MMR, #{rank.rank_percentile}%)")
        if rank.win_streak:
            direction = "^" if rank.win_streak_type == "win" else "v"
            print(f"    Streak: {direction}{rank.win_streak}")

Results are cached for 5 minutes (tracker.gg update interval).

6. GUI / Overlay

from PySide6.QtWidgets import QApplication
from nixwrap.gui import (
    create_overlay, WindowConfig, WindowType,
    Painter, Color, THEME_DARK, FadeAnimation,
)

class MyOverlay:
    def __init__(self):
        self.win = create_overlay(600, 200, corner_radius=12, opacity=0.95)
        self.win._paint = self._paint
        self.win.snap_to_bottom_center(margin=20)

    def _paint(self, painter_q):
        p = Painter(painter_q)
        p.fill_rect(0, 0, 600, 200,
                     THEME_DARK.background.with_alpha(216), radius=12)
        p.stroke_rect(0, 0, 599, 199,
                       THEME_DARK.divider, width=1, radius=12)
        p.draw_text("Hello Rocket League!", 20, 40,
                     color=THEME_DARK.text_primary)

app = QApplication([])
overlay = MyOverlay()
app.exec()

7. Launch.log Parser

from nixwrap.log import parse_log

info = parse_log()

print(info.session.username)
print(info.session.rich_presence)

if info.game:
    print(info.game.playlist_id)
    print(info.game.playlist_name)
    print(info.game.game_class)
    print(info.game.map_name)
    print(info.game.server_ip, info.game.server_port)
    print(info.game.region)

info = parse_log(verify=False)  # skip Stats API check, return whatever the log has

# verify=True (default) checks the Stats API before returning game data
# so you don't get stale playlist/map info from a previous session.

8. PsyNet Config API

from nixwrap.utils import (
    fetch_psynet_config, get_online_playlists,
    get_maps_for_playlist, get_special_events,
)

config = fetch_psynet_config(939334844)

playlists = get_online_playlists(config)
print(playlists[11])   # Doubles
print(playlists[27])   # Hoops

maps = get_maps_for_playlist(config, 11)
print(len(maps))        # number of maps in rotation

for e in get_special_events(config):
    print(e["Title"])

Optional Dependencies

Extra Packages What you get
[tracker] curl-cffi better tracker.gg support
[gui] PySide6 Overlay windows, painter, colors, fonts, animations
[input] dualsense-controller, keyboard, bundled hidapi.dll Xbox (XInput), PS5 DualSense, keyboard hotkey detection
[all] all of the above Everything

Requirements

  • Python >= 3.10
  • pycryptodome >= 3.18 (save file AES)
  • psutil >= 5.9 (process detection)

Acknowledgements

Contributing

Do you want to make this library even better? Contributions are highly encouraged and appreciated.

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

nixwrap_rl-0.1.3.tar.gz (149.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nixwrap_rl-0.1.3-py3-none-any.whl (158.8 kB view details)

Uploaded Python 3

File details

Details for the file nixwrap_rl-0.1.3.tar.gz.

File metadata

  • Download URL: nixwrap_rl-0.1.3.tar.gz
  • Upload date:
  • Size: 149.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for nixwrap_rl-0.1.3.tar.gz
Algorithm Hash digest
SHA256 fe5dc5af62e514d03ce5fff337f8b9801228d8bf6f17f6fc860e7efcb6038daf
MD5 adf7915e061aaf4fc979271ba5ac5378
BLAKE2b-256 7a007331f604c2850d59a8d6ffa2da4dc0ab5e7f3c272f7451eb494775f1568e

See more details on using hashes here.

File details

Details for the file nixwrap_rl-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: nixwrap_rl-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 158.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for nixwrap_rl-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 08aa69a2f9c40f7a7c088b516cd24ef84f0666441c9801ce8336ce40cf04f89d
MD5 282fbd0820e8ff5e84f2b94f55a45678
BLAKE2b-256 c87cf12e1e60576462d5cee3af487884031d860ec7e8d96c997dfb42252895f8

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