infinitode.py 1.1.6__tar.gz → 1.2.1__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.
Files changed (20) hide show
  1. {infinitode.py-1.1.6/infinitode.py.egg-info → infinitode_py-1.2.1}/PKG-INFO +52 -6
  2. infinitode.py-1.1.6/PKG-INFO → infinitode_py-1.2.1/README.md +255 -228
  3. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/__init__.py +40 -39
  4. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/core.py +668 -508
  5. infinitode_py-1.2.1/infinitode/daily_quest.py +27 -0
  6. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/errors.py +39 -25
  7. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/player.py +13 -2
  8. infinitode.py-1.1.6/README.md → infinitode_py-1.2.1/infinitode.py.egg-info/PKG-INFO +59 -1
  9. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode.py.egg-info/SOURCES.txt +3 -1
  10. infinitode_py-1.2.1/tests/test_core.py +306 -0
  11. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/badge.py +0 -0
  12. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/leaderboard.py +0 -0
  13. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/py.typed +0 -0
  14. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/score.py +0 -0
  15. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode/utils.py +0 -0
  16. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode.py.egg-info/dependency_links.txt +0 -0
  17. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode.py.egg-info/requires.txt +0 -0
  18. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/infinitode.py.egg-info/top_level.txt +0 -0
  19. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/setup.cfg +0 -0
  20. {infinitode.py-1.1.6 → infinitode_py-1.2.1}/setup.py +0 -0
@@ -1,12 +1,21 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: infinitode.py
3
- Version: 1.1.6
3
+ Version: 1.2.1
4
4
  Summary: A python wrapper for the Infinitode 2 API.
5
5
  Home-page: https://github.com/Sprylos/infinitode.py
6
6
  Author: Sprylos
7
7
  License: MIT
8
- Platform: UNKNOWN
9
8
  Description-Content-Type: text/markdown
9
+ Requires-Dist: aiohttp
10
+ Requires-Dist: lxml
11
+ Requires-Dist: bs4
12
+ Dynamic: author
13
+ Dynamic: description
14
+ Dynamic: description-content-type
15
+ Dynamic: home-page
16
+ Dynamic: license
17
+ Dynamic: requires-dist
18
+ Dynamic: summary
10
19
 
11
20
  # Infinitode.py
12
21
 
@@ -53,6 +62,11 @@ Parameters:
53
62
  - `mode` (optional): One of `'score'`, `'waves'`. Defaults to `'score'`.
54
63
  - `difficulty` (optional): One of `'EASY'`, `'NORMAL'`, `'ENDLESS_I'`. Defaults to `'NORMAL'`.
55
64
 
65
+ The immutable `infinitode.SUPPORTED_MAPS`, `infinitode.SUPPORTED_MODES`, and
66
+ `infinitode.SUPPORTED_DIFFICULTIES` tuples contain the values accepted by the
67
+ current library. `infinitode.GAME_API_VERSION` exposes the game API version used
68
+ for JSON API calls.
69
+
56
70
  #### Player Score on a Specific Map
57
71
 
58
72
  Retrieve the score of a specific player on a particular map.
@@ -112,6 +126,15 @@ Retrieve the top 200 players of today's daily quest or a specified date.
112
126
  dq_leaderboard = await API.daily_quest_leaderboards("2024-12-05")
113
127
  ```
114
128
 
129
+ Retrieve metadata for the currently active Daily Quest. The reset timestamp is
130
+ also available as `reset_timestamp`, and `mapname` is derived from `quest_id`.
131
+
132
+ ```python
133
+ dq = await API.daily_quest_info()
134
+ print(dq.date, dq.quest_id, dq.mapname)
135
+ print(dq.end_timestamp, dq.reset_timestamp, dq.data_hash)
136
+ ```
137
+
115
138
  ---
116
139
 
117
140
  ### Working with Leaderboards
@@ -161,7 +184,9 @@ print(len(top_10))
161
184
  Retrieve detailed player information.
162
185
 
163
186
  ```python
164
- player = await API.player("U-E9BP-FSN9-H6ENMQ")
187
+ player = await API.player(playerid="U-E9BP-FSN9-H6ENMQ")
188
+ # Or look up a case-insensitive, exact nickname:
189
+ player = await API.player(nickname="EuphoRowan")
165
190
  ```
166
191
 
167
192
  Attributes include:
@@ -186,6 +211,29 @@ await player.fetch_skill_point(API)
186
211
  print(player.daily_quest.rank, player.skill_point.score)
187
212
  ```
188
213
 
214
+ An invalid argument raises `infinitode.errors.BadArgument`, and an exact lookup
215
+ with no matching player raises its `PlayerNotFound` subclass. HTTP and JSON API
216
+ failures raise `APIError`; unexpected changes to parsed HTML raise `ParseError`.
217
+
218
+ ---
219
+
220
+ ### Experimental features
221
+
222
+ `Session.search_players()` performs an unauthenticated, case-insensitive
223
+ substring search of player nicknames:
224
+
225
+ ```python
226
+ players = await API.search_players("eupho", limit=20)
227
+ for result in players:
228
+ print(result.playerid, result.nickname, result.level, result.has_avatar)
229
+ ```
230
+
231
+ Each `PlayerSummary` contains only the verified `playerid`, `nickname`, `level`,
232
+ and `has_avatar` fields. The upstream page returns at most 100 results and does
233
+ not offer pagination. This feature parses an HTML page rather than a stable JSON
234
+ API, so upstream markup changes may cause `ParseError` until the parser is
235
+ updated.
236
+
189
237
  ---
190
238
 
191
239
  ### Beta Scores
@@ -224,5 +272,3 @@ asyncio.run(main())
224
272
 
225
273
  - Some data (e.g., seasonal leaderboard, players) require additional parsing and will take longer to process.
226
274
  - Do not abuse this API wrapper for any kind of malicious action.
227
-
228
-
@@ -1,228 +1,255 @@
1
- Metadata-Version: 2.1
2
- Name: infinitode.py
3
- Version: 1.1.6
4
- Summary: A python wrapper for the Infinitode 2 API.
5
- Home-page: https://github.com/Sprylos/infinitode.py
6
- Author: Sprylos
7
- License: MIT
8
- Platform: UNKNOWN
9
- Description-Content-Type: text/markdown
10
-
11
- # Infinitode.py
12
-
13
- An asynchronous Python wrapper for the Infinitode-2 API using `async`-`await` syntax.
14
-
15
- ---
16
-
17
- ## Installation
18
-
19
- Install the library via pip:
20
-
21
- ```bash
22
- pip install infinitode.py
23
- ```
24
-
25
- ---
26
-
27
- ## Showcase
28
-
29
- ### Setting Up a Session
30
-
31
- Create a session to communicate with Rainy's API. Use the `with` statement to ensure the session closes properly.
32
- Alternatively you can can simply call `Session.close()` once you don't need it anymore.
33
-
34
- ```python
35
- import asyncio
36
- import infinitode
37
-
38
- async def main():
39
- async with infinitode.Session() as API:
40
- # Your API calls go here
41
- pass
42
-
43
- asyncio.run(main())
44
- ```
45
-
46
- ---
47
-
48
- ### Fetching Leaderboard Data
49
-
50
- Parameters:
51
- - `mapname`: The map identifier (e.g., "5.1" or "4.b1" or "zecred").
52
- - `playerid` (sometimes optional): The player's unique identifier.
53
- - `mode` (optional): One of `'score'`, `'waves'`. Defaults to `'score'`.
54
- - `difficulty` (optional): One of `'EASY'`, `'NORMAL'`, `'ENDLESS_I'`. Defaults to `'NORMAL'`.
55
-
56
- #### Player Score on a Specific Map
57
-
58
- Retrieve the score of a specific player on a particular map.
59
-
60
- ```python
61
- score_5_1 = await API.leaderboards_rank(
62
- mapname="5.1",
63
- playerid="U-E9BP-FSN9-H6ENMQ",
64
- mode="score",
65
- difficulty="NORMAL"
66
- )
67
- ```
68
-
69
- #### Top 200 Leaderboard on a Specific Map
70
-
71
- Retrieve the leaderboard of the top 200 wave scores on 5.1.
72
-
73
- ```python
74
- leaderboard_5_1 = await API.leaderboards(
75
- mapname=5.1,
76
- mode="waves"
77
- )
78
- ```
79
-
80
- #### Runtime Leaderboard
81
-
82
- Fetch the leaderboard displayed during gameplay. This provides additional percentile information.
83
-
84
- ```python
85
- runtime_5_1 = await API.runtime_leaderboards(
86
- mapname=5.1,
87
- playerid="U-E9BP-FSN9-H6ENMQ",
88
- difficulty="ENDLESS_I"
89
- )
90
- ```
91
-
92
- ---
93
-
94
- #### Skill Point Leaderboard
95
-
96
- Get the top 3 skill point owners. Optionally specify a `playerid`.
97
-
98
- ```python
99
- sp_leaderboard = await API.skill_point_leaderboard(
100
- playerid="U-E9BP-FSN9-H6ENMQ"
101
- )
102
- ```
103
-
104
-
105
- #### Daily Quest Leaderboard
106
-
107
- Retrieve the top 200 players of today's daily quest or a specified date.
108
-
109
- - `date`: `YYYY-MM-DD` (string) or `datetime.datetime`.
110
-
111
- ```python
112
- dq_leaderboard = await API.daily_quest_leaderboards("2024-12-05")
113
- ```
114
-
115
- ---
116
-
117
- ### Working with Leaderboards
118
-
119
- A leaderboard is a sequence of scores with additional utility functions.
120
-
121
- #### Access Score and Leaderboard Attributes
122
-
123
- Leaderboards always have these attributes:
124
- - `mapname`, `mode`, `difficulty`, `total`
125
-
126
- And optionally these:
127
- - `date`, `season`, `player` (will return a score object)
128
-
129
- Scores always have these attributes:
130
- - `playerid`, `rank`, `score`, `mapname`, `mode`, `difficulty`
131
-
132
- And optionally these:
133
- - `has_pfp`, `level`, `nickname`, `pinned_badge`, `position`, `top`, `total`, `player` (will return a Player object if fetched beforehand)
134
-
135
- #### Example for printing attributes, scores, and leaderboards
136
-
137
- ```python
138
- for score in leaderboard_5_1:
139
- print(score.nickname)
140
- score.print_score() # Helper method
141
-
142
- leaderboard_5_1.print_scores()
143
- ```
144
-
145
- #### Slice a Leaderboard
146
-
147
- Retrieve a subset of the leaderboard:
148
-
149
- ```python
150
- top_1 = leaderboard_5_1[0]
151
- top_10 = leaderboard_5_1[0:10]
152
- print(len(top_10))
153
- ```
154
-
155
- ---
156
-
157
- ### Player Information
158
-
159
- #### Fetch Player Data
160
-
161
- Retrieve detailed player information.
162
-
163
- ```python
164
- player = await API.player("U-E9BP-FSN9-H6ENMQ")
165
- ```
166
-
167
- Attributes include:
168
- - `playerid`, `nickname`, `level`, `xp`, `season_level`, `total_score`, and many more.
169
-
170
- #### Get Player Scores
171
-
172
- Use the `score` method to access specific map scores.
173
-
174
- ```python
175
- player.score(5.1).print_score()
176
- ```
177
-
178
- #### Fetch Daily Quest and Skill Point Scores
179
-
180
- Use additional API calls to retrieve daily quest and skill point scores:
181
-
182
- ```python
183
- await player.fetch_daily_quest(API)
184
- await player.fetch_skill_point(API)
185
-
186
- print(player.daily_quest.rank, player.skill_point.score)
187
- ```
188
-
189
- ---
190
-
191
- ### Beta Scores
192
-
193
- Almost all API calls support an additional `beta` boolean parameter. This will make a request to the beta servers instead. No guarantees for it working.
194
-
195
- ```python
196
- leaderboard_5_1 = await API.leaderboards(mapname=5.1, mode='waves', beta=True)
197
- ```
198
-
199
-
200
- ### Logging
201
-
202
- Set up logging to monitor requests and responses.
203
-
204
- - `INFO`: Logs every request.
205
- - `DEBUG`: Logs server responses.
206
-
207
- ```python
208
- import infinitode
209
- import asyncio
210
- import logging
211
-
212
- logging.basicConfig(level=logging.INFO)
213
-
214
- async def main():
215
- async with infinitode.Session() as API:
216
- await API.leaderboards("6.3")
217
-
218
- asyncio.run(main())
219
- ```
220
-
221
- ---
222
-
223
- ### Notes
224
-
225
- - Some data (e.g., seasonal leaderboard, players) require additional parsing and will take longer to process.
226
- - Do not abuse this API wrapper for any kind of malicious action.
227
-
228
-
1
+ # Infinitode.py
2
+
3
+ An asynchronous Python wrapper for the Infinitode-2 API using `async`-`await` syntax.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ Install the library via pip:
10
+
11
+ ```bash
12
+ pip install infinitode.py
13
+ ```
14
+
15
+ ---
16
+
17
+ ## Showcase
18
+
19
+ ### Setting Up a Session
20
+
21
+ Create a session to communicate with Rainy's API. Use the `with` statement to ensure the session closes properly.
22
+ Alternatively you can can simply call `Session.close()` once you don't need it anymore.
23
+
24
+ ```python
25
+ import asyncio
26
+ import infinitode
27
+
28
+ async def main():
29
+ async with infinitode.Session() as API:
30
+ # Your API calls go here
31
+ pass
32
+
33
+ asyncio.run(main())
34
+ ```
35
+
36
+ ---
37
+
38
+ ### Fetching Leaderboard Data
39
+
40
+ Parameters:
41
+ - `mapname`: The map identifier (e.g., "5.1" or "4.b1" or "zecred").
42
+ - `playerid` (sometimes optional): The player's unique identifier.
43
+ - `mode` (optional): One of `'score'`, `'waves'`. Defaults to `'score'`.
44
+ - `difficulty` (optional): One of `'EASY'`, `'NORMAL'`, `'ENDLESS_I'`. Defaults to `'NORMAL'`.
45
+
46
+ The immutable `infinitode.SUPPORTED_MAPS`, `infinitode.SUPPORTED_MODES`, and
47
+ `infinitode.SUPPORTED_DIFFICULTIES` tuples contain the values accepted by the
48
+ current library. `infinitode.GAME_API_VERSION` exposes the game API version used
49
+ for JSON API calls.
50
+
51
+ #### Player Score on a Specific Map
52
+
53
+ Retrieve the score of a specific player on a particular map.
54
+
55
+ ```python
56
+ score_5_1 = await API.leaderboards_rank(
57
+ mapname="5.1",
58
+ playerid="U-E9BP-FSN9-H6ENMQ",
59
+ mode="score",
60
+ difficulty="NORMAL"
61
+ )
62
+ ```
63
+
64
+ #### Top 200 Leaderboard on a Specific Map
65
+
66
+ Retrieve the leaderboard of the top 200 wave scores on 5.1.
67
+
68
+ ```python
69
+ leaderboard_5_1 = await API.leaderboards(
70
+ mapname=5.1,
71
+ mode="waves"
72
+ )
73
+ ```
74
+
75
+ #### Runtime Leaderboard
76
+
77
+ Fetch the leaderboard displayed during gameplay. This provides additional percentile information.
78
+
79
+ ```python
80
+ runtime_5_1 = await API.runtime_leaderboards(
81
+ mapname=5.1,
82
+ playerid="U-E9BP-FSN9-H6ENMQ",
83
+ difficulty="ENDLESS_I"
84
+ )
85
+ ```
86
+
87
+ ---
88
+
89
+ #### Skill Point Leaderboard
90
+
91
+ Get the top 3 skill point owners. Optionally specify a `playerid`.
92
+
93
+ ```python
94
+ sp_leaderboard = await API.skill_point_leaderboard(
95
+ playerid="U-E9BP-FSN9-H6ENMQ"
96
+ )
97
+ ```
98
+
99
+
100
+ #### Daily Quest Leaderboard
101
+
102
+ Retrieve the top 200 players of today's daily quest or a specified date.
103
+
104
+ - `date`: `YYYY-MM-DD` (string) or `datetime.datetime`.
105
+
106
+ ```python
107
+ dq_leaderboard = await API.daily_quest_leaderboards("2024-12-05")
108
+ ```
109
+
110
+ Retrieve metadata for the currently active Daily Quest. The reset timestamp is
111
+ also available as `reset_timestamp`, and `mapname` is derived from `quest_id`.
112
+
113
+ ```python
114
+ dq = await API.daily_quest_info()
115
+ print(dq.date, dq.quest_id, dq.mapname)
116
+ print(dq.end_timestamp, dq.reset_timestamp, dq.data_hash)
117
+ ```
118
+
119
+ ---
120
+
121
+ ### Working with Leaderboards
122
+
123
+ A leaderboard is a sequence of scores with additional utility functions.
124
+
125
+ #### Access Score and Leaderboard Attributes
126
+
127
+ Leaderboards always have these attributes:
128
+ - `mapname`, `mode`, `difficulty`, `total`
129
+
130
+ And optionally these:
131
+ - `date`, `season`, `player` (will return a score object)
132
+
133
+ Scores always have these attributes:
134
+ - `playerid`, `rank`, `score`, `mapname`, `mode`, `difficulty`
135
+
136
+ And optionally these:
137
+ - `has_pfp`, `level`, `nickname`, `pinned_badge`, `position`, `top`, `total`, `player` (will return a Player object if fetched beforehand)
138
+
139
+ #### Example for printing attributes, scores, and leaderboards
140
+
141
+ ```python
142
+ for score in leaderboard_5_1:
143
+ print(score.nickname)
144
+ score.print_score() # Helper method
145
+
146
+ leaderboard_5_1.print_scores()
147
+ ```
148
+
149
+ #### Slice a Leaderboard
150
+
151
+ Retrieve a subset of the leaderboard:
152
+
153
+ ```python
154
+ top_1 = leaderboard_5_1[0]
155
+ top_10 = leaderboard_5_1[0:10]
156
+ print(len(top_10))
157
+ ```
158
+
159
+ ---
160
+
161
+ ### Player Information
162
+
163
+ #### Fetch Player Data
164
+
165
+ Retrieve detailed player information.
166
+
167
+ ```python
168
+ player = await API.player(playerid="U-E9BP-FSN9-H6ENMQ")
169
+ # Or look up a case-insensitive, exact nickname:
170
+ player = await API.player(nickname="EuphoRowan")
171
+ ```
172
+
173
+ Attributes include:
174
+ - `playerid`, `nickname`, `level`, `xp`, `season_level`, `total_score`, and many more.
175
+
176
+ #### Get Player Scores
177
+
178
+ Use the `score` method to access specific map scores.
179
+
180
+ ```python
181
+ player.score(5.1).print_score()
182
+ ```
183
+
184
+ #### Fetch Daily Quest and Skill Point Scores
185
+
186
+ Use additional API calls to retrieve daily quest and skill point scores:
187
+
188
+ ```python
189
+ await player.fetch_daily_quest(API)
190
+ await player.fetch_skill_point(API)
191
+
192
+ print(player.daily_quest.rank, player.skill_point.score)
193
+ ```
194
+
195
+ An invalid argument raises `infinitode.errors.BadArgument`, and an exact lookup
196
+ with no matching player raises its `PlayerNotFound` subclass. HTTP and JSON API
197
+ failures raise `APIError`; unexpected changes to parsed HTML raise `ParseError`.
198
+
199
+ ---
200
+
201
+ ### Experimental features
202
+
203
+ `Session.search_players()` performs an unauthenticated, case-insensitive
204
+ substring search of player nicknames:
205
+
206
+ ```python
207
+ players = await API.search_players("eupho", limit=20)
208
+ for result in players:
209
+ print(result.playerid, result.nickname, result.level, result.has_avatar)
210
+ ```
211
+
212
+ Each `PlayerSummary` contains only the verified `playerid`, `nickname`, `level`,
213
+ and `has_avatar` fields. The upstream page returns at most 100 results and does
214
+ not offer pagination. This feature parses an HTML page rather than a stable JSON
215
+ API, so upstream markup changes may cause `ParseError` until the parser is
216
+ updated.
217
+
218
+ ---
219
+
220
+ ### Beta Scores
221
+
222
+ Almost all API calls support an additional `beta` boolean parameter. This will make a request to the beta servers instead. No guarantees for it working.
223
+
224
+ ```python
225
+ leaderboard_5_1 = await API.leaderboards(mapname=5.1, mode='waves', beta=True)
226
+ ```
227
+
228
+
229
+ ### Logging
230
+
231
+ Set up logging to monitor requests and responses.
232
+
233
+ - `INFO`: Logs every request.
234
+ - `DEBUG`: Logs server responses.
235
+
236
+ ```python
237
+ import infinitode
238
+ import asyncio
239
+ import logging
240
+
241
+ logging.basicConfig(level=logging.INFO)
242
+
243
+ async def main():
244
+ async with infinitode.Session() as API:
245
+ await API.leaderboards("6.3")
246
+
247
+ asyncio.run(main())
248
+ ```
249
+
250
+ ---
251
+
252
+ ### Notes
253
+
254
+ - Some data (e.g., seasonal leaderboard, players) require additional parsing and will take longer to process.
255
+ - Do not abuse this API wrapper for any kind of malicious action.
@@ -1,39 +1,40 @@
1
- """
2
- Infinitode API Wrapper
3
- ~~~~~~~~~~~~~~~~~~~
4
-
5
- An asynchronous wrapper for the Infinitode API.
6
- """
7
-
8
- __author__ = "Sprylos"
9
- __title__ = "infinitode.py"
10
- __version__ = "1.1.6"
11
- __license__ = """MIT License
12
-
13
- Copyright (c) 2025 Sprylos
14
-
15
- Permission is hereby granted, free of charge, to any person obtaining a copy
16
- of this software and associated documentation files (the "Software"), to deal
17
- in the Software without restriction, including without limitation the rights
18
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
- copies of the Software, and to permit persons to whom the Software is
20
- furnished to do so, subject to the following conditions:
21
-
22
- The above copyright notice and this permission notice shall be included in all
23
- copies or substantial portions of the Software.
24
-
25
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- SOFTWARE."""
32
-
33
- from .badge import *
34
- from .core import *
35
- from .leaderboard import *
36
- from .player import *
37
- from .score import *
38
- from . import errors as errors
39
- from . import utils as utils
1
+ """
2
+ Infinitode API Wrapper
3
+ ~~~~~~~~~~~~~~~~~~~
4
+
5
+ An asynchronous wrapper for the Infinitode API.
6
+ """
7
+
8
+ __author__ = "Sprylos"
9
+ __title__ = "infinitode.py"
10
+ __version__ = "1.2.1"
11
+ __license__ = """MIT License
12
+
13
+ Copyright (c) 2026 Sprylos
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE."""
32
+
33
+ from .badge import *
34
+ from .core import *
35
+ from .daily_quest import *
36
+ from .leaderboard import *
37
+ from .player import *
38
+ from .score import *
39
+ from . import errors as errors
40
+ from . import utils as utils