rlstatsapi 0.1.3__tar.gz → 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/LICENSE +21 -21
- rlstatsapi-0.1.5/PKG-INFO +149 -0
- rlstatsapi-0.1.5/README.md +126 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/pyproject.toml +47 -42
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/setup.cfg +4 -4
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi/__init__.py +33 -2
- rlstatsapi-0.1.5/src/rlstatsapi/__main__.py +142 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi/client.py +100 -16
- rlstatsapi-0.1.5/src/rlstatsapi/config.py +243 -0
- rlstatsapi-0.1.5/src/rlstatsapi/models.py +61 -0
- rlstatsapi-0.1.5/src/rlstatsapi/state.py +110 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi/types.py +392 -383
- rlstatsapi-0.1.5/src/rlstatsapi.egg-info/PKG-INFO +149 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi.egg-info/SOURCES.txt +5 -1
- rlstatsapi-0.1.5/src/rlstatsapi.egg-info/entry_points.txt +2 -0
- rlstatsapi-0.1.5/tests/test_config.py +123 -0
- rlstatsapi-0.1.3/PKG-INFO +0 -194
- rlstatsapi-0.1.3/README.md +0 -170
- rlstatsapi-0.1.3/src/rlstatsapi/models.py +0 -13
- rlstatsapi-0.1.3/src/rlstatsapi.egg-info/PKG-INFO +0 -194
- rlstatsapi-0.1.3/tests/test_client.py +0 -48
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi/events.py +0 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi/py.typed +0 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi.egg-info/dependency_links.txt +0 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi.egg-info/requires.txt +0 -0
- {rlstatsapi-0.1.3 → rlstatsapi-0.1.5}/src/rlstatsapi.egg-info/top_level.txt +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Manu
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Manu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rlstatsapi
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: Rocket League Stats API client
|
|
5
|
+
Author: Manuel Cabral
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/manucabral/RocketLeagueStatsAPI
|
|
8
|
+
Project-URL: Repository, https://github.com/manucabral/RocketLeagueStatsAPI
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/manucabral/RocketLeagueStatsAPI/issues
|
|
10
|
+
Keywords: rocket-league,stats,socket,asyncio
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Games/Entertainment
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.11
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
<img width="600" alt="rlstatsapi-logo" src="https://github.com/manucabral/RocketLeagueStatsAPI/blob/main/docs/assets/social-preview.png" />
|
|
25
|
+
|
|
26
|
+
# Rocket League Stats API
|
|
27
|
+
[](https://github.com/psf/black) [](https://pypi.org/project/rlstatsapi/) [](https://github.com/manucabral/RocketLeagueStatsAPI/actions/workflows/pylint.yml)
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
`rlstatsapi` is a small Python client for reading live Rocket League Stats API events over a local TCP socket.
|
|
31
|
+
|
|
32
|
+
- Full docs: [manucabral.github.io/RocketLeagueStatsAPI](https://manucabral.github.io/RocketLeagueStatsAPI/)
|
|
33
|
+
- Release history: [CHANGELOG.md](CHANGELOG.md)
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
From [PyPI](https://pypi.org/project/rlstatsapi/):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install rlstatsapi
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
From GitHub:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install git+https://github.com/manucabral/RocketLeagueStatsAPI.git
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Rocket League setup
|
|
50
|
+
|
|
51
|
+
Automatic setup from Python:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from rlstatsapi import configure_stats_api
|
|
55
|
+
|
|
56
|
+
configure_stats_api(enabled=True, port=49123, packet_send_rate=30)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Manual setup:
|
|
60
|
+
|
|
61
|
+
`Documents\My Games\Rocket League\TAGame\Config\TAStatsAPI.ini`
|
|
62
|
+
|
|
63
|
+
```ini
|
|
64
|
+
[TAGame.MatchStatsExporter_TA]
|
|
65
|
+
Port=49123
|
|
66
|
+
PacketSendRate=30
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
In both cases, restart Rocket League after changing the config file.
|
|
70
|
+
|
|
71
|
+
Config discovery is currently Windows-first and targets common user config locations.
|
|
72
|
+
|
|
73
|
+
## Quick start
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import asyncio
|
|
77
|
+
from rlstatsapi import StatsClient
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
async def main() -> None:
|
|
81
|
+
async with StatsClient() as client:
|
|
82
|
+
client.on_any(lambda msg: print(msg.event, msg.data))
|
|
83
|
+
await asyncio.Event().wait()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
asyncio.run(main())
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Demos
|
|
90
|
+
|
|
91
|
+
### All events
|
|
92
|
+
|
|
93
|
+

|
|
94
|
+
|
|
95
|
+
### UI
|
|
96
|
+
|
|
97
|
+

|
|
98
|
+
|
|
99
|
+
## CLI
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
rlstatsapi status
|
|
103
|
+
rlstatsapi enable --port 49123 --rate 30
|
|
104
|
+
rlstatsapi listen --event GoalScored
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
You can also listen to multiple events:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
rlstatsapi listen --event GoalScored --event MatchEnded --event MatchCreated
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Typing
|
|
114
|
+
|
|
115
|
+
For the best editor experience, use `cast_event_data(...)` or `msg.as_type(...)`.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
from rlstatsapi.models import EventMessage
|
|
119
|
+
from rlstatsapi.types import GoalScoredPayload, cast_event_data
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def on_goal(msg: EventMessage) -> None:
|
|
123
|
+
data: GoalScoredPayload = cast_event_data("GoalScored", msg.data)
|
|
124
|
+
print(data.get("Scorer", {}).get("Name"))
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## More
|
|
128
|
+
|
|
129
|
+
- Full docs: [manucabral.github.io/RocketLeagueStatsAPI](https://manucabral.github.io/RocketLeagueStatsAPI/)
|
|
130
|
+
- Examples: [examples/](examples)
|
|
131
|
+
- Release history: [CHANGELOG.md](CHANGELOG.md)
|
|
132
|
+
|
|
133
|
+
## Notes
|
|
134
|
+
|
|
135
|
+
- In current Rocket League builds this endpoint behaves like a TCP JSON stream in practice.
|
|
136
|
+
- Some fields, such as `MatchGuid`, are only present in online/LAN contexts.
|
|
137
|
+
|
|
138
|
+
## Disclaimer
|
|
139
|
+
|
|
140
|
+
This project is an independent, community-made library and is **not affiliated with, endorsed by, or sponsored by Psyonix or Epic Games**.
|
|
141
|
+
|
|
142
|
+
Rocket League and related trademarks are the property of their respective owners.
|
|
143
|
+
Use this library at your own risk and in compliance with Rocket League’s terms and policies.
|
|
144
|
+
|
|
145
|
+
## Contributors
|
|
146
|
+
|
|
147
|
+
<a href="https://github.com/manucabral/RocketLeagueStatsAPI/graphs/contributors">
|
|
148
|
+
<img src="https://contrib.rocks/image?repo=manucabral/RocketLeagueStatsAPI" alt="Contributors" />
|
|
149
|
+
</a>
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
<img width="600" alt="rlstatsapi-logo" src="https://github.com/manucabral/RocketLeagueStatsAPI/blob/main/docs/assets/social-preview.png" />
|
|
2
|
+
|
|
3
|
+
# Rocket League Stats API
|
|
4
|
+
[](https://github.com/psf/black) [](https://pypi.org/project/rlstatsapi/) [](https://github.com/manucabral/RocketLeagueStatsAPI/actions/workflows/pylint.yml)
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
`rlstatsapi` is a small Python client for reading live Rocket League Stats API events over a local TCP socket.
|
|
8
|
+
|
|
9
|
+
- Full docs: [manucabral.github.io/RocketLeagueStatsAPI](https://manucabral.github.io/RocketLeagueStatsAPI/)
|
|
10
|
+
- Release history: [CHANGELOG.md](CHANGELOG.md)
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
From [PyPI](https://pypi.org/project/rlstatsapi/):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install rlstatsapi
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
From GitHub:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install git+https://github.com/manucabral/RocketLeagueStatsAPI.git
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Rocket League setup
|
|
27
|
+
|
|
28
|
+
Automatic setup from Python:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from rlstatsapi import configure_stats_api
|
|
32
|
+
|
|
33
|
+
configure_stats_api(enabled=True, port=49123, packet_send_rate=30)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Manual setup:
|
|
37
|
+
|
|
38
|
+
`Documents\My Games\Rocket League\TAGame\Config\TAStatsAPI.ini`
|
|
39
|
+
|
|
40
|
+
```ini
|
|
41
|
+
[TAGame.MatchStatsExporter_TA]
|
|
42
|
+
Port=49123
|
|
43
|
+
PacketSendRate=30
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
In both cases, restart Rocket League after changing the config file.
|
|
47
|
+
|
|
48
|
+
Config discovery is currently Windows-first and targets common user config locations.
|
|
49
|
+
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
import asyncio
|
|
54
|
+
from rlstatsapi import StatsClient
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
async def main() -> None:
|
|
58
|
+
async with StatsClient() as client:
|
|
59
|
+
client.on_any(lambda msg: print(msg.event, msg.data))
|
|
60
|
+
await asyncio.Event().wait()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
asyncio.run(main())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Demos
|
|
67
|
+
|
|
68
|
+
### All events
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
### UI
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
## CLI
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
rlstatsapi status
|
|
80
|
+
rlstatsapi enable --port 49123 --rate 30
|
|
81
|
+
rlstatsapi listen --event GoalScored
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
You can also listen to multiple events:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
rlstatsapi listen --event GoalScored --event MatchEnded --event MatchCreated
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Typing
|
|
91
|
+
|
|
92
|
+
For the best editor experience, use `cast_event_data(...)` or `msg.as_type(...)`.
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from rlstatsapi.models import EventMessage
|
|
96
|
+
from rlstatsapi.types import GoalScoredPayload, cast_event_data
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def on_goal(msg: EventMessage) -> None:
|
|
100
|
+
data: GoalScoredPayload = cast_event_data("GoalScored", msg.data)
|
|
101
|
+
print(data.get("Scorer", {}).get("Name"))
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## More
|
|
105
|
+
|
|
106
|
+
- Full docs: [manucabral.github.io/RocketLeagueStatsAPI](https://manucabral.github.io/RocketLeagueStatsAPI/)
|
|
107
|
+
- Examples: [examples/](examples)
|
|
108
|
+
- Release history: [CHANGELOG.md](CHANGELOG.md)
|
|
109
|
+
|
|
110
|
+
## Notes
|
|
111
|
+
|
|
112
|
+
- In current Rocket League builds this endpoint behaves like a TCP JSON stream in practice.
|
|
113
|
+
- Some fields, such as `MatchGuid`, are only present in online/LAN contexts.
|
|
114
|
+
|
|
115
|
+
## Disclaimer
|
|
116
|
+
|
|
117
|
+
This project is an independent, community-made library and is **not affiliated with, endorsed by, or sponsored by Psyonix or Epic Games**.
|
|
118
|
+
|
|
119
|
+
Rocket League and related trademarks are the property of their respective owners.
|
|
120
|
+
Use this library at your own risk and in compliance with Rocket League’s terms and policies.
|
|
121
|
+
|
|
122
|
+
## Contributors
|
|
123
|
+
|
|
124
|
+
<a href="https://github.com/manucabral/RocketLeagueStatsAPI/graphs/contributors">
|
|
125
|
+
<img src="https://contrib.rocks/image?repo=manucabral/RocketLeagueStatsAPI" alt="Contributors" />
|
|
126
|
+
</a>
|
|
@@ -1,42 +1,47 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["setuptools>=69", "wheel"]
|
|
3
|
-
build-backend = "setuptools.build_meta"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "rlstatsapi"
|
|
7
|
-
version = "0.1.
|
|
8
|
-
description = "Rocket League Stats API client"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.11"
|
|
11
|
-
license =
|
|
12
|
-
authors = [{ name = "Manuel Cabral" }]
|
|
13
|
-
keywords = ["rocket-league", "stats", "socket", "asyncio"]
|
|
14
|
-
classifiers = [
|
|
15
|
-
"Programming Language :: Python :: 3",
|
|
16
|
-
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"Topic ::
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
[
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rlstatsapi"
|
|
7
|
+
version = "0.1.5"
|
|
8
|
+
description = "Rocket League Stats API client"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Manuel Cabral" }]
|
|
13
|
+
keywords = ["rocket-league", "stats", "socket", "asyncio"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Topic :: Games/Entertainment",
|
|
19
|
+
"Topic :: Software Development :: Libraries",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/manucabral/RocketLeagueStatsAPI"
|
|
24
|
+
Repository = "https://github.com/manucabral/RocketLeagueStatsAPI"
|
|
25
|
+
"Bug Tracker" = "https://github.com/manucabral/RocketLeagueStatsAPI/issues"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
rlstatsapi = "rlstatsapi.__main__:main"
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.23"]
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
asyncio_mode = "auto"
|
|
35
|
+
testpaths = ["tests"]
|
|
36
|
+
markers = [
|
|
37
|
+
"integration: requires a live Rocket League exporter to be running",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.setuptools]
|
|
41
|
+
package-dir = {"" = "src"}
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["src"]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.package-data]
|
|
47
|
+
rlstatsapi = ["py.typed"]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[egg_info]
|
|
2
|
-
tag_build =
|
|
3
|
-
tag_date = 0
|
|
4
|
-
|
|
1
|
+
[egg_info]
|
|
2
|
+
tag_build =
|
|
3
|
+
tag_date = 0
|
|
4
|
+
|
|
@@ -1,11 +1,29 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""
|
|
2
|
+
Public package surface for rlstatsapi.
|
|
3
|
+
|
|
4
|
+
Re-exports the client, envelope model, known event constants, and typed payload
|
|
5
|
+
helpers so consumers can import from `rlstatsapi` directly.
|
|
6
|
+
"""
|
|
2
7
|
|
|
3
8
|
from importlib.metadata import PackageNotFoundError
|
|
4
9
|
from importlib.metadata import version as _pkg_version
|
|
5
10
|
|
|
6
11
|
from .client import StatsClient
|
|
12
|
+
from .config import (
|
|
13
|
+
DEFAULT_PACKET_SEND_RATE,
|
|
14
|
+
DEFAULT_STATS_API_FILENAME,
|
|
15
|
+
DEFAULT_STATS_API_PORT,
|
|
16
|
+
StatsAPIConfigStatus,
|
|
17
|
+
candidate_stats_api_paths,
|
|
18
|
+
configure_stats_api,
|
|
19
|
+
find_stats_api_config,
|
|
20
|
+
get_stats_api_status,
|
|
21
|
+
set_stats_api_enabled,
|
|
22
|
+
set_stats_api_port,
|
|
23
|
+
)
|
|
7
24
|
from .events import KNOWN_EVENTS
|
|
8
|
-
from .models import EventMessage
|
|
25
|
+
from .models import ClientMetrics, EventMessage, MatchStateSnapshot
|
|
26
|
+
from .state import MatchStateTracker
|
|
9
27
|
from .types import (
|
|
10
28
|
BallHitPayload,
|
|
11
29
|
ClockUpdatedSecondsPayload,
|
|
@@ -40,8 +58,21 @@ except PackageNotFoundError:
|
|
|
40
58
|
__all__ = [
|
|
41
59
|
"__version__",
|
|
42
60
|
"StatsClient",
|
|
61
|
+
"StatsAPIConfigStatus",
|
|
43
62
|
"EventMessage",
|
|
63
|
+
"ClientMetrics",
|
|
64
|
+
"MatchStateSnapshot",
|
|
65
|
+
"MatchStateTracker",
|
|
44
66
|
"KNOWN_EVENTS",
|
|
67
|
+
"DEFAULT_PACKET_SEND_RATE",
|
|
68
|
+
"DEFAULT_STATS_API_FILENAME",
|
|
69
|
+
"DEFAULT_STATS_API_PORT",
|
|
70
|
+
"candidate_stats_api_paths",
|
|
71
|
+
"find_stats_api_config",
|
|
72
|
+
"get_stats_api_status",
|
|
73
|
+
"set_stats_api_enabled",
|
|
74
|
+
"set_stats_api_port",
|
|
75
|
+
"configure_stats_api",
|
|
45
76
|
"EventName",
|
|
46
77
|
"TypedEventMessage",
|
|
47
78
|
"KnownEventMessage",
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Command-line entrypoint for common rlstatsapi setup and debugging tasks."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import asyncio
|
|
7
|
+
import json
|
|
8
|
+
from dataclasses import asdict
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Sequence
|
|
11
|
+
|
|
12
|
+
from .client import StatsClient
|
|
13
|
+
from .config import (
|
|
14
|
+
DEFAULT_PACKET_SEND_RATE,
|
|
15
|
+
DEFAULT_STATS_API_PORT,
|
|
16
|
+
configure_stats_api,
|
|
17
|
+
get_stats_api_status,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def main(argv: Sequence[str] | None = None) -> int:
|
|
22
|
+
"""Parse CLI args and dispatch the requested command."""
|
|
23
|
+
parser = _build_parser()
|
|
24
|
+
args = parser.parse_args(argv)
|
|
25
|
+
return args.func(args)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
29
|
+
parser = argparse.ArgumentParser(prog="rlstatsapi")
|
|
30
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
31
|
+
|
|
32
|
+
status_parser = subparsers.add_parser(
|
|
33
|
+
"status",
|
|
34
|
+
help="Show the current TAStatsAPI.ini status.",
|
|
35
|
+
)
|
|
36
|
+
status_parser.add_argument(
|
|
37
|
+
"--path", type=Path, help="Explicit TAStatsAPI.ini path."
|
|
38
|
+
)
|
|
39
|
+
status_parser.set_defaults(func=_run_status)
|
|
40
|
+
|
|
41
|
+
enable_parser = subparsers.add_parser(
|
|
42
|
+
"enable",
|
|
43
|
+
help="Enable the Rocket League Stats API in TAStatsAPI.ini.",
|
|
44
|
+
)
|
|
45
|
+
enable_parser.add_argument(
|
|
46
|
+
"--path", type=Path, help="Explicit TAStatsAPI.ini path."
|
|
47
|
+
)
|
|
48
|
+
enable_parser.add_argument("--port", type=int, default=DEFAULT_STATS_API_PORT)
|
|
49
|
+
enable_parser.add_argument(
|
|
50
|
+
"--rate",
|
|
51
|
+
type=int,
|
|
52
|
+
default=DEFAULT_PACKET_SEND_RATE,
|
|
53
|
+
help="PacketSendRate to write when enabling the exporter.",
|
|
54
|
+
)
|
|
55
|
+
enable_parser.set_defaults(func=_run_enable)
|
|
56
|
+
|
|
57
|
+
disable_parser = subparsers.add_parser(
|
|
58
|
+
"disable",
|
|
59
|
+
help="Disable the Rocket League Stats API in TAStatsAPI.ini.",
|
|
60
|
+
)
|
|
61
|
+
disable_parser.add_argument(
|
|
62
|
+
"--path", type=Path, help="Explicit TAStatsAPI.ini path."
|
|
63
|
+
)
|
|
64
|
+
disable_parser.add_argument("--port", type=int, default=DEFAULT_STATS_API_PORT)
|
|
65
|
+
disable_parser.set_defaults(func=_run_disable)
|
|
66
|
+
|
|
67
|
+
listen_parser = subparsers.add_parser(
|
|
68
|
+
"listen",
|
|
69
|
+
help="Connect to the local exporter and print live events.",
|
|
70
|
+
)
|
|
71
|
+
listen_parser.add_argument("--host", default="127.0.0.1")
|
|
72
|
+
listen_parser.add_argument("--port", type=int, default=DEFAULT_STATS_API_PORT)
|
|
73
|
+
listen_parser.add_argument(
|
|
74
|
+
"--event",
|
|
75
|
+
action="append",
|
|
76
|
+
default=[],
|
|
77
|
+
help="Filter to one or more event names. Repeat the flag to add more.",
|
|
78
|
+
)
|
|
79
|
+
listen_parser.add_argument(
|
|
80
|
+
"--raw",
|
|
81
|
+
action="store_true",
|
|
82
|
+
help="Include the raw transport JSON when available.",
|
|
83
|
+
)
|
|
84
|
+
listen_parser.set_defaults(func=_run_listen)
|
|
85
|
+
|
|
86
|
+
return parser
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _run_status(args: argparse.Namespace) -> int:
|
|
90
|
+
status = get_stats_api_status(args.path)
|
|
91
|
+
print(json.dumps(asdict(status), indent=2))
|
|
92
|
+
return 0
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _run_enable(args: argparse.Namespace) -> int:
|
|
96
|
+
status = configure_stats_api(
|
|
97
|
+
enabled=True,
|
|
98
|
+
port=args.port,
|
|
99
|
+
packet_send_rate=args.rate,
|
|
100
|
+
path=args.path,
|
|
101
|
+
)
|
|
102
|
+
print(json.dumps(asdict(status), indent=2))
|
|
103
|
+
print("Restart Rocket League after changing the config file.")
|
|
104
|
+
return 0
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _run_disable(args: argparse.Namespace) -> int:
|
|
108
|
+
status = configure_stats_api(
|
|
109
|
+
enabled=False,
|
|
110
|
+
port=args.port,
|
|
111
|
+
packet_send_rate=DEFAULT_PACKET_SEND_RATE,
|
|
112
|
+
path=args.path,
|
|
113
|
+
)
|
|
114
|
+
print(json.dumps(asdict(status), indent=2))
|
|
115
|
+
print("Restart Rocket League after changing the config file.")
|
|
116
|
+
return 0
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _run_listen(args: argparse.Namespace) -> int:
|
|
120
|
+
return asyncio.run(_listen(args))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
async def _listen(args: argparse.Namespace) -> int:
|
|
124
|
+
async with StatsClient(
|
|
125
|
+
host=args.host,
|
|
126
|
+
port=args.port,
|
|
127
|
+
include_raw=args.raw,
|
|
128
|
+
) as client:
|
|
129
|
+
print("Listening for Rocket League events. Press Ctrl+C to stop.")
|
|
130
|
+
async for message in client.events(*args.event):
|
|
131
|
+
payload = {
|
|
132
|
+
"event": message.event,
|
|
133
|
+
"data": message.data,
|
|
134
|
+
}
|
|
135
|
+
if args.raw:
|
|
136
|
+
payload["raw"] = message.raw
|
|
137
|
+
print(json.dumps(payload, indent=2, ensure_ascii=False))
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
raise SystemExit(main())
|