diff --git a/osuRepy/replay.py b/osuRepy/replay.py index 150802a..f248841 100644 --- a/osuRepy/replay.py +++ b/osuRepy/replay.py @@ -39,33 +39,33 @@ def lzma_compress(data): ]) class Replay: - mode = Serializable(osuModes.STANDARD, TYPE_BYTE) - osu_version = Serializable(20131216, TYPE_INT) - beatmap_hash = Serializable(b"d41d8cd98f00b204e9800998ecf8427e", TYPE_STRING) - player_name = Serializable(b"osu!", TYPE_STRING) - score_hash = Serializable(b"d41d8cd98f00b204e9800998ecf8427e", TYPE_STRING) + _mode = Serializable(osuModes.STANDARD, TYPE_BYTE) + _osu_version = Serializable(20131216, TYPE_INT) + _beatmap_hash = Serializable(b"d41d8cd98f00b204e9800998ecf8427e", TYPE_STRING) + _player_name = Serializable(b"osu!", TYPE_STRING) + _score_hash = Serializable(b"d41d8cd98f00b204e9800998ecf8427e", TYPE_STRING) - score_300s = Serializable(0, TYPE_USHORT) - score_100s = Serializable(0, TYPE_USHORT) - score_50s = Serializable(0, TYPE_USHORT) - score_gekis = Serializable(0, TYPE_USHORT) - score_katus = Serializable(0, TYPE_USHORT) - score_miss = Serializable(0, TYPE_USHORT) - score = Serializable(0, TYPE_INT) - combo = Serializable(0, TYPE_USHORT) - perfect = Serializable(True, TYPE_BOOL) + _score_300s = Serializable(0, TYPE_USHORT) + _score_100s = Serializable(0, TYPE_USHORT) + _score_50s = Serializable(0, TYPE_USHORT) + _score_gekis = Serializable(0, TYPE_USHORT) + _score_katus = Serializable(0, TYPE_USHORT) + _score_miss = Serializable(0, TYPE_USHORT) + _score = Serializable(0, TYPE_INT) + _combo = Serializable(0, TYPE_USHORT) + _perfect = Serializable(True, TYPE_BOOL) - mods = Serializable(osuMods.NOMOD, TYPE_INT) + _mods = Serializable(osuMods.NOMOD, TYPE_INT) - lifebar_graph = Serializable(b"0|1,", TYPE_STRING) - timestamp = Serializable(0, TYPE_ULLONG) + _lifebar_graph = Serializable(b"0|1,", TYPE_STRING) + _timestamp = Serializable(0, TYPE_ULLONG) - replay_data = Serializable(b"", TYPE_BYTESTREAM, post = lzma_compress) + _replay_data = Serializable(b"", TYPE_BYTESTREAM, post = lzma_compress) - online_score_id = Serializable(0, TYPE_ULLONG) + _online_score_id= Serializable(0, TYPE_ULLONG) # Marker (Only used as attribute section marker for auto-serializing) - end_of_attributes = None + _end_of_attributes = None def __init__(self, **kwargs): allowed_kwargs = { @@ -79,56 +79,85 @@ class Replay: if k in allowed_kwargs.keys(): allowed_kwargs[k](v) # Run callback func + # -------------------------------------------------------------------------- # Set validators ----------------------------------------------------------- def set_mode(self, mode): if mode > 3 or mode < 0: raise Exception("Invalid mode") - self.mode.value = mode + self._mode.value = mode def set_osu_version(self, osu_version): if type(osu_version) is not int: raise Exception("osu! version must be an int") - self.osu_version.value = osu_version + self._osu_version.value = osu_version def set_beatmap_hash(self, md5_hash): if len(md5_hash) != 32 or len([x for x in md5_hash if x in string.hexdigits]) != 32: raise Exception("Invalid beatmap hash") - self.beatmap_hash.value = md5_hash + self._beatmap_hash.value = md5_hash - def set_beatmap(self, filepath): + def set_beatmap_file(self, filepath): if not isfile(filepath): raise Exception("Beatmap file not found") with open(filepath, "rb") as f: - self.beatmap_hash.value = md5_file(f) + self._beatmap_hash.value = md5_file(f) def set_player_name(self, player_name): - self.player_name.value = player_name + self._player_name.value = player_name def set_score_hash(self, md5_hash): if type(md5_hash) is bytes: md5_hash = md5_hash.decode() if len(md5_hash) != 32 or len([x for x in md5_hash if x in string.hexdigits]) != 32: raise Exception("Invalid replay hash") - self.score_hash.value = md5_hash.encode() + self._score_hash.value = md5_hash.encode() + + def set_score(self, score = None, combo = None, s300 = None, s100 = None, s50 = None, sgekis = None, skatus = None, miss = None): + if type(score) is int: self._score.value = score + if type(combo) is int: self._combo.value = combo + if type(s300) is int: self._score_300s.value = s300 + if type(s100) is int: self._score_100s.value = s100 + if type(s50) is int: self._score_50s.value = s50 + if type(sgekis) is int: self._score_gekis.value = sgekis + if type(skatus) is int: self._score_katus.value = skatus + if type(miss) is int: self._score_miss.value = miss def set_mods(self, mods): if mods < 0 or mods > (1 << 30) - 1: raise Exception("Mods are out of range") - self.mods.value = mods + self._mods.value = mods + + def set_lifebar_graph(self, graph): + t_graph = type(graph) + if t_graph is list: + self._lifebar_graph.value = b"".join(graph) + elif t_graph is str: + self._lifebar_graph.value = graph.encode() + elif t_graph is bytes: + self._lifebar_graph.value = graph + else: + raise Exception("Invalid lifebar data") + + def set_timestamp(self, timestamp, use_unix = True): + if use_unix: + timestamp += 62135599380000 # offset + timestamp *= 10 ** 4 + + self._timestamp.value = timestamp # -------------------------------------------------------------------------- # Update variables --------------------------------------------------------- def update_perfect(self): - m = [self.score_100s.value, self.score_50s.value, self.score_katus.value, self.score_miss.value] - self.perfect.value = sum(m) == 0 + m = [self._score_100s.value, self._score_50s.value, self._score_katus.value, self._score_miss.value] + self._perfect.value = sum(m) == 0 def update_score_hash(self): self.set_score_hash( md5_str("%d%s%s%s%d%d" % ( - self.combo.value, "osu", self.player_name.value, - self.beatmap_hash.value, self.score.value, self.get_rank() + self._combo.value, "osu", self._player_name.value, + self._beatmap_hash.value, self._score.value, self.get_rank() )) ) @@ -140,27 +169,27 @@ class Replay: # Get / Helpers ------------------------------------------------------------ def get_hits(self): - return sum([self.score_300s.value, self.score_100s.value, self.score_50s.value]) + return sum([self._score_300s.value, self._score_100s.value, self._score_50s.value]) def get_possible_hits(self): - return self.get_hits() + self.score_miss.value + return self.get_hits() + self._score_miss.value def get_rank(self): # We dont give out F ranks around here hits = self.get_possible_hits() if hits == 0: raise Exception("Can not calculate rank without any score data") - r300 = self.score_300s.value / hits - r50 = self.score_50s.value / hits - h = osuMods.any_enabled(self.mods.value, osuMods.HIDDEN | osuMods.FLASHLIGHT) + r300 = self._score_300s.value / hits + r50 = self._score_50s.value / hits + h = osuMods.any_enabled(self._mods.value, osuMods.HIDDEN | osuMods.FLASHLIGHT) if r300 == 1: return osuRanks.SSH if h else osuRanks.SS - if r300 > .9 and r50 <= .01 and self.score_miss.value == 0: + if r300 > .9 and r50 <= .01 and self._score_miss.value == 0: return osuRanks.SH if h else osuRanks.S - if r300 > .8 and self.score_miss.value == 0 or r300 > .9: + if r300 > .8 and self._score_miss.value == 0 or r300 > .9: return osuRanks.A - if r300 > .7 and self.score_miss.value == 0 or r300 > .8: + if r300 > .7 and self._score_miss.value == 0 or r300 > .8: return osuRanks.B if r300 > .6: return osuRanks.C @@ -175,7 +204,7 @@ class Replay: self.write(_frame) return - self.replay_data.value += bytes(frame) + self._replay_data.value += bytes(frame) # -------------------------------------------------------------------------- # IO replay data ----------------------------------------------------------- @@ -187,7 +216,7 @@ class Replay: attribs = [ a for a in self.__dir__() if not a.startswith("__") ] for attrib in attribs: - if attrib == "end_of_attributes": + if attrib == "_end_of_attributes": break serializer.add( self.__getattribute__(attrib) ) # Add value to serializer diff --git a/test.osr b/test.osr deleted file mode 100644 index a96e5d9..0000000 Binary files a/test.osr and /dev/null differ diff --git a/test.py b/test.py index ea889f4..cd06970 100644 --- a/test.py +++ b/test.py @@ -4,7 +4,7 @@ from osuRepy.replay import Replay replay = Replay() replay.write( ReplayFrame(2, 3, 4, 4) ) -replay.score_300s.value = 20 -replay.timestamp.value = 635592412124124124 # Wed Feb 11 2015 09:03:52 GMT+0100 (Central European Standard Time) +replay.set_score(s300 = 10) +replay.set_timestamp( 1552466941 )# Wed Feb 11 2015 09:03:52 GMT+0100 (Central European Standard Time) replay.save("test.osr")