osudroid-api-wrapper 0.0.2__tar.gz → 0.0.4__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.
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/LICENSE +3 -1
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/PKG-INFO +6 -3
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/pyproject.toml +1 -1
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/base/beatmap.py +2 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/base/mods.py +8 -2
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay.py +51 -32
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/replayobjectdata.py +8 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/structs/profile.py +3 -2
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/PKG-INFO +6 -3
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/setup.cfg +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/__init__.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/__init__.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/base/__init__.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/base/player.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/cursordata.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/cursoroccurrence.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/cursoroccurrencegroup.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/hitresult.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay_data/movementtype.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/score.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/structs/__init__.py +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/SOURCES.txt +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/dependency_links.txt +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/requires.txt +0 -0
- {osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 FireRedz
|
|
4
|
+
Copyright (c) 2021 Rian8337
|
|
5
|
+
Copyright (c) 2025 unclem2
|
|
4
6
|
|
|
5
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
8
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: osudroid-api-wrapper
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Python api wrapper for osu!droid
|
|
5
5
|
Author-email: unclem <mannringyt11@gmail.com>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
|
-
Copyright (c)
|
|
8
|
+
Copyright (c) 2021 FireRedz
|
|
9
|
+
Copyright (c) 2021 Rian8337
|
|
10
|
+
Copyright (c) 2025 unclem2
|
|
9
11
|
|
|
10
12
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
13
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -37,3 +39,4 @@ Requires-Dist: beautifulsoup4>=4.10.0
|
|
|
37
39
|
Requires-Dist: javaobj-py3>=0.4.4
|
|
38
40
|
Requires-Dist: stream_unzip>=0.0.99
|
|
39
41
|
Requires-Dist: python-dotenv>=1.0.0
|
|
42
|
+
Dynamic: license-file
|
|
@@ -13,7 +13,7 @@ class Mods:
|
|
|
13
13
|
return cls([mod_abbreviations.get(mod, mod) for mod in mods.split(",")])
|
|
14
14
|
|
|
15
15
|
@classmethod
|
|
16
|
-
def from_droid_replay(cls, mods:
|
|
16
|
+
def from_droid_replay(cls, mods: list):
|
|
17
17
|
mod_mapping = {
|
|
18
18
|
"MOD_NOFAIL": "NF", "MOD_EASY": "EZ", "MOD_HIDDEN": "HD",
|
|
19
19
|
"MOD_HARDROCK": "HR", "MOD_SUDDENDEATH": "SD", "MOD_DOUBLETIME": "DT",
|
|
@@ -22,7 +22,7 @@ class Mods:
|
|
|
22
22
|
"MOD_AUTO": "AT", "MOD_PRECISE": "PR", "MOD_REALLYEASY": "REZ",
|
|
23
23
|
"MOD_SMALLCIRCLES": "SC", "MOD_PERFECT": "PF", "MOD_SUDDENDEATH": "SU",
|
|
24
24
|
}
|
|
25
|
-
return cls([mod_mapping.get(mod, mod) for mod in mods
|
|
25
|
+
return cls([mod_mapping.get(mod, mod) for mod in mods])
|
|
26
26
|
|
|
27
27
|
@classmethod
|
|
28
28
|
def from_droid_api(cls, mods: dict):
|
|
@@ -31,3 +31,9 @@ class Mods:
|
|
|
31
31
|
return instance
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
@property
|
|
35
|
+
def to_dict(self):
|
|
36
|
+
return {
|
|
37
|
+
"mods": self.mods,
|
|
38
|
+
"speed_multiplier": self.speed_multiplier
|
|
39
|
+
}
|
{osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/replay.py
RENAMED
|
@@ -31,6 +31,7 @@ from stream_unzip import stream_unzip
|
|
|
31
31
|
import javaobj
|
|
32
32
|
import struct
|
|
33
33
|
import io
|
|
34
|
+
from .base.mods import Mods
|
|
34
35
|
from .replay_data.movementtype import MovementType
|
|
35
36
|
from .replay_data.cursordata import CursorData
|
|
36
37
|
from .replay_data.hitresult import HitResult
|
|
@@ -53,8 +54,10 @@ class Replay:
|
|
|
53
54
|
self.hit0: int = 0
|
|
54
55
|
self.score: int = 0
|
|
55
56
|
self.combo: int = 0
|
|
57
|
+
self.rank: str = None
|
|
58
|
+
self.accuracy: float = 0.0
|
|
56
59
|
self.username: str = None
|
|
57
|
-
self.parsed_mods:
|
|
60
|
+
self.parsed_mods: Mods = []
|
|
58
61
|
self.converted_mods: list = []
|
|
59
62
|
self.__buffer_offset: int = 0
|
|
60
63
|
self.cursor_data: list = []
|
|
@@ -65,6 +68,43 @@ class Replay:
|
|
|
65
68
|
while chunk := f.read(65536):
|
|
66
69
|
yield chunk
|
|
67
70
|
|
|
71
|
+
def __calculate_rank(self):
|
|
72
|
+
total_hits = self.hit300 + self.hit100 + self.hit50 + self.hit0
|
|
73
|
+
have_h_mods = False
|
|
74
|
+
for mod in self.converted_mods:
|
|
75
|
+
if mod == "HD" or mod == "FL":
|
|
76
|
+
have_h_mods = True
|
|
77
|
+
break
|
|
78
|
+
hit300ratio = self.hit300 / total_hits
|
|
79
|
+
|
|
80
|
+
if hit300ratio == 1:
|
|
81
|
+
self.rank = "XH" if have_h_mods else "X"
|
|
82
|
+
return self
|
|
83
|
+
elif hit300ratio >= 0.9:
|
|
84
|
+
if self.hit50 / total_hits <= 0.01 and self.hit0 == 0:
|
|
85
|
+
self.rank = "SH" if have_h_mods else "S"
|
|
86
|
+
return self
|
|
87
|
+
self.rank = "A"
|
|
88
|
+
return self
|
|
89
|
+
elif hit300ratio >= 0.8:
|
|
90
|
+
if self.hit0 == 0:
|
|
91
|
+
self.rank = "A"
|
|
92
|
+
return self
|
|
93
|
+
self.rank = "B"
|
|
94
|
+
return self
|
|
95
|
+
elif hit300ratio >= 0.7:
|
|
96
|
+
if self.hit0 == 0:
|
|
97
|
+
self.rank = "B"
|
|
98
|
+
return self
|
|
99
|
+
self.rank = "C"
|
|
100
|
+
return self
|
|
101
|
+
elif hit300ratio >= 0.6:
|
|
102
|
+
self.rank = "C"
|
|
103
|
+
return self
|
|
104
|
+
else:
|
|
105
|
+
self.rank = "D"
|
|
106
|
+
return self
|
|
107
|
+
|
|
68
108
|
|
|
69
109
|
|
|
70
110
|
def __read_byte(self, replay_data):
|
|
@@ -87,33 +127,6 @@ class Replay:
|
|
|
87
127
|
self.__buffer_offset += 4
|
|
88
128
|
return struct.unpack(">f", replay_data.read(4))[0]
|
|
89
129
|
|
|
90
|
-
def __droid_replay_mods_to_std(self):
|
|
91
|
-
mod_mapping = {
|
|
92
|
-
"MOD_NOFAIL": "NF",
|
|
93
|
-
"MOD_EASY": "EZ",
|
|
94
|
-
"MOD_HIDDEN": "HD",
|
|
95
|
-
"MOD_HARDROCK": "HR",
|
|
96
|
-
"MOD_SUDDENDEATH": "SD",
|
|
97
|
-
"MOD_DOUBLETIME": "DT",
|
|
98
|
-
"MOD_RELAX": "RX",
|
|
99
|
-
"MOD_HALFTIME": "HT",
|
|
100
|
-
"MOD_NIGHTCORE": "NC",
|
|
101
|
-
"MOD_FLASHLIGHT": "FL",
|
|
102
|
-
"MOD_SCOREV2": "V2",
|
|
103
|
-
"MOD_AUTOPILOT": "AP",
|
|
104
|
-
"MOD_AUTO": "AT",
|
|
105
|
-
"MOD_PRECISE": "PR",
|
|
106
|
-
"MOD_REALLYEASY": "REZ",
|
|
107
|
-
"MOD_SMALLCIRCLES": "SC",
|
|
108
|
-
"MOD_PERFECT": "PF",
|
|
109
|
-
"MOD_SUDDENDEATH": "SU",
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
for mod in self.parsed_mods:
|
|
113
|
-
if mod in mod_mapping:
|
|
114
|
-
self.converted_mods.append(mod_mapping[mod])
|
|
115
|
-
return self.converted_mods
|
|
116
|
-
|
|
117
130
|
def __parse_movement_data(self, replay_data):
|
|
118
131
|
replay_data = io.BytesIO(replay_data)
|
|
119
132
|
size = self.__read_int(replay_data)
|
|
@@ -192,7 +205,7 @@ class Replay:
|
|
|
192
205
|
|
|
193
206
|
self.replay_obj = javaobj.v2.loads(data_buffer.getvalue())
|
|
194
207
|
|
|
195
|
-
for fields in self.replay_obj[0].
|
|
208
|
+
for fields in self.replay_obj[0].__dict__['field_data'].values():
|
|
196
209
|
for field, value in fields.items():
|
|
197
210
|
if field.name == 'version':
|
|
198
211
|
self.version = value
|
|
@@ -207,14 +220,16 @@ class Replay:
|
|
|
207
220
|
self.hit0, self.score, self.combo) = struct.unpack(">Qiiiiiiii", io.BytesIO(self.replay_obj[4].data).read(40))
|
|
208
221
|
self.username = self.replay_obj[5].value
|
|
209
222
|
|
|
210
|
-
for field in self.replay_obj[6].
|
|
223
|
+
for field in self.replay_obj[6].__dict__['field_data'].values():
|
|
211
224
|
for field, value in field.items():
|
|
212
225
|
if field.name == "elements":
|
|
213
226
|
for element in value:
|
|
214
227
|
self.parsed_mods.append(element.value)
|
|
215
228
|
break
|
|
216
229
|
|
|
217
|
-
self.
|
|
230
|
+
self.converted_mods = Mods.from_droid_replay(self.parsed_mods).mods
|
|
231
|
+
self.accuracy = round(((300 * self.hit300 + 100 * self.hit100 + 50 * self.hit50) / (300 * (self.hit300 + self.hit100 + self.hit50 + self.hit0))) * 100, 2)
|
|
232
|
+
self.__calculate_rank()
|
|
218
233
|
|
|
219
234
|
if self.version >= 4:
|
|
220
235
|
modifiers = self.replay_obj[7].value.split("|")
|
|
@@ -248,10 +263,14 @@ class Replay:
|
|
|
248
263
|
self.__parse_movement_data(replay_data.getvalue())
|
|
249
264
|
print(self.__buffer_offset)
|
|
250
265
|
self.__parse_hitresult_data(replay_data.getvalue())
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
return self
|
|
251
270
|
|
|
252
271
|
def __str__(self):
|
|
253
272
|
string = ""
|
|
254
|
-
for key, value in self.
|
|
273
|
+
for key, value in self.__dict__.items():
|
|
255
274
|
if key == "replay_obj" or key == "replay_file" or key == "cursor_data":
|
|
256
275
|
continue
|
|
257
276
|
|
|
@@ -34,5 +34,13 @@ class ReplayObjectData:
|
|
|
34
34
|
self.tickset:List[bool] = tickset
|
|
35
35
|
self.result:hitresult.HitResult = result
|
|
36
36
|
|
|
37
|
+
@property
|
|
38
|
+
def to_dict(self):
|
|
39
|
+
return {
|
|
40
|
+
"accuracy": self.accuracy,
|
|
41
|
+
"tickset": self.tickset,
|
|
42
|
+
"result": self.result
|
|
43
|
+
}
|
|
44
|
+
|
|
37
45
|
|
|
38
46
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from classes.score import Score
|
|
2
|
-
from classes.base.player import Player
|
|
1
|
+
from ..classes.score import Score
|
|
2
|
+
from ..classes.base.player import Player
|
|
3
3
|
from typing import List
|
|
4
4
|
import bs4
|
|
5
5
|
import requests
|
|
@@ -56,6 +56,7 @@ class Profile():
|
|
|
56
56
|
resp = requests.get(url)
|
|
57
57
|
soup = bs4.BeautifulSoup(resp.text, 'html.parser')
|
|
58
58
|
profile.player = Player._parse_from_bsoup(soup)
|
|
59
|
+
profile.player.uid = uid
|
|
59
60
|
profile.__get_recent_scores(soup)
|
|
60
61
|
profile.__get_top_scores(soup)
|
|
61
62
|
return profile
|
{osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper.egg-info/PKG-INFO
RENAMED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: osudroid-api-wrapper
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Python api wrapper for osu!droid
|
|
5
5
|
Author-email: unclem <mannringyt11@gmail.com>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
8
|
-
Copyright (c)
|
|
8
|
+
Copyright (c) 2021 FireRedz
|
|
9
|
+
Copyright (c) 2021 Rian8337
|
|
10
|
+
Copyright (c) 2025 unclem2
|
|
9
11
|
|
|
10
12
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
13
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -37,3 +39,4 @@ Requires-Dist: beautifulsoup4>=4.10.0
|
|
|
37
39
|
Requires-Dist: javaobj-py3>=0.4.4
|
|
38
40
|
Requires-Dist: stream_unzip>=0.0.99
|
|
39
41
|
Requires-Dist: python-dotenv>=1.0.0
|
|
42
|
+
Dynamic: license-file
|
|
File without changes
|
{osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{osudroid_api_wrapper-0.0.2 → osudroid_api_wrapper-0.0.4}/src/osudroid_api_wrapper/classes/score.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|