### Install osrparse using pip Source: https://kszlim.github.io/osu-replay-parser/index.html Install the osrparse library using pip. This is the recommended way to install the package. ```bash pip install osrparse ``` -------------------------------- ### Pack Replay to String Source: https://kszlim.github.io/osu-replay-parser/appendix.html Use pack to get the string representation of the Replay object in .osr format, suitable for writing to a file. ```python replay.pack() ``` -------------------------------- ### Main Unpack Method Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Initiates the unpacking process by first unpacking the game mode from the replay data. ```python def unpack(self): mode = GameMode(self.unpack_once("b")) ``` -------------------------------- ### Create Replay from File Path Source: https://kszlim.github.io/osu-replay-parser/appendix.html Use Replay.from_path to create a Replay object from an existing .osr file. ```python Replay.from_path(path) ``` -------------------------------- ### Create Replay from File Path Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Use this static method to create a Replay object by providing the path to an .osr file. It handles opening the file and passing it to `from_file`. ```python with open(path, "rb") as f: return Replay.from_file(f) ``` -------------------------------- ### Create Replay Object from Path, File, or String Source: https://kszlim.github.io/osu-replay-parser/_sources/parsing-replays.rst.txt Use Replay.from_path, Replay.from_file, or Replay.from_string to create a Replay object. Replay.from_path is the most common method. ```python from osrparse import Replay # from a path replay = Replay.from_path("path/to/osr.osr") # or from an opened file object with open("path/to/osr.osr") as f: replay = Replay.from_file(f) # or from a string with open("path/to/osr.osr") as f: replay_string = f.read() replay = Replay.from_string(replay_string) ``` -------------------------------- ### Create Replay from File Object Source: https://kszlim.github.io/osu-replay-parser/appendix.html Use Replay.from_file to create a Replay object from an open file-like object. ```python Replay.from_file(file) ``` -------------------------------- ### Create Replay Object from File Object Source: https://kszlim.github.io/osu-replay-parser/parsing-replays.html Use Replay.from_file() with an opened file object to create a Replay object. Ensure the file is opened in binary mode if necessary. ```python from osrparse import Replay # or from an opened file object with open("path/to/osr.osr") as f: replay = Replay.from_file(f) ``` -------------------------------- ### Key Bindings (Standard) Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Enumeration for keys pressed during osu!standard gameplay. ```APIDOC ## Enum Key ### Description A key that can be pressed during osu!standard gameplay - mouse 1 and 2, key 1 and 2, and smoke. ### Members - **M1** (1) - **M2** (2) - **K1** (4) - **K2** (8) - **SMOKE** (16) ``` -------------------------------- ### Create Replay from File Object Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Instantiate a Replay object from an already open file-like object. This method reads the entire file content and passes it to `from_string`. ```python data = file.read() return Replay.from_string(data) ``` -------------------------------- ### Create Replay Object from Path Source: https://kszlim.github.io/osu-replay-parser/parsing-replays.html Use Replay.from_path() to create a Replay object directly from a file path. This is the most common method for parsing replay files. ```python from osrparse import Replay # from a path replay = Replay.from_path("path/to/osr.osr") ``` -------------------------------- ### Pack Full Replay Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Assembles all replay components into a single byte string according to the OSU replay file format. This method orchestrates the packing of individual data fields. ```python def pack(self): r = self.replay data = b"" data += self.pack_byte(r.mode.value) data += self.pack_int(r.game_version) data += self.pack_string(r.beatmap_hash) data += self.pack_string(r.username) data += self.pack_string(r.replay_hash) data += self.pack_short(r.count_300) data += self.pack_short(r.count_100) data += self.pack_short(r.count_50) data += self.pack_short(r.count_geki) data += self.pack_short(r.count_katu) data += self.pack_short(r.count_miss) data += self.pack_int(r.score) data += self.pack_short(r.max_combo) data += self.pack_byte(r.perfect) data += self.pack_int(r.mods.value) data += self.pack_life_bar() data += self.pack_timestamp() data += self.pack_replay_data() data += self.pack_long(r.replay_id) return data ``` -------------------------------- ### Replay Object and Creation Source: https://kszlim.github.io/osu-replay-parser/appendix.html Details the Replay object structure and static methods for creating Replay instances from various sources. ```APIDOC ## Replay Object Structure The `Replay` object represents a single osu! replay. ### Attributes: - **mode** (GameMode) - The game mode this replay was played on. - **game_version** (int) - The game version this replay was played on. - **beatmap_hash** (str) - The hash of the beatmap this replay was played on. - **username** (str) - The user that played this replay. - **replay_hash** (str) - The hash of this replay. - **count_300** (int) - The number of 300 judgments. - **count_100** (int) - The number of 100 judgments. - **count_50** (int) - The number of 50 judgments. - **count_geki** (int) - The number of geki judgments. - **count_katu** (int) - The number of katu judgments. - **count_miss** (int) - The number of misses. - **score** (int) - The score of this replay. - **max_combo** (int) - The maximum combo attained. - **perfect** (bool) - Whether this replay was perfect. - **mods** (Mod) - The mods this replay was played with. - **life_bar_graph** (Optional[List[LifeBarState]]) - The life bar of this replay over time. - **replay_data** (List[ReplayEvent]) - The replay data, including cursor position and keys pressed. - **replay_id** (int) - The replay id, or 0 if not submitted. - **rng_seed** (Optional[int]) - The rng seed, or None if not present. ### Static Methods for Creation: #### `Replay.from_path(path)` Creates a new `Replay` object from the `.osr` file at the given `path`. - **Parameters**: - **path** (str or os.PathLike) - The path to the osr file. #### `Replay.from_file(file)` Creates a new `Replay` object from an open file object. - **Parameters**: - **file** (file-like) - The file object to read from. #### `Replay.from_string(data)` Creates a new `Replay` object from a string containing `.osr` data. - **Parameters**: - **data** (str) - The data to parse. ### Methods for Writing: #### `replay.write_path(path, *args, dict_size=None, mode=None)` Writes the replay to the given `path`. - **Parameters**: - **path** (str or os.PathLike) - The path to where to write the replay. #### `replay.write_file(file, *args, dict_size=None, mode=None)` Writes the replay to an open file object. - **Parameters**: - **file** (file-like) - The file object to write to. #### `replay.pack(*args, dict_size=None, mode=None)` Returns the text representing this `Replay`, in `.osr` format. - **Returns**: - str - The text representing this `Replay`, in `.osr` format. ``` -------------------------------- ### Create Replay Object from String Source: https://kszlim.github.io/osu-replay-parser/parsing-replays.html Use Replay.from_string() to create a Replay object from a string containing the replay file's content. The string should represent the full replay data. ```python from osrparse import Replay # or from a string with open("path/to/osr.osr") as f: replay_string = f.read() replay = Replay.from_string(replay_string) ``` -------------------------------- ### Replay Parsing Methods Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Methods to create a Replay object from various sources including file paths, file objects, and raw strings. ```APIDOC ## Replay.from_path ### Description Creates a new Replay object from the .osr file at the given path. ### Parameters #### Path Parameters - **path** (str or os.PathLike) - Required - The path to the osr file to read from. ### Response - **Replay** - The parsed replay object. ## Replay.from_file ### Description Creates a new Replay object from an open file object. ### Parameters #### Request Body - **file** (file-like) - Required - The file object to read from. ### Response - **Replay** - The parsed replay object. ## Replay.from_string ### Description Creates a new Replay object from a string containing .osr data. ### Parameters #### Request Body - **data** (str) - Required - The data to parse. ### Response - **Replay** - The parsed replay object. ``` -------------------------------- ### Pack Replay Data to String Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Converts the Replay object into a string formatted as a valid .osr file. This string can then be written to a file or transmitted. ```python return _Packer(self, dict_size=dict_size, mode=mode).pack() ``` -------------------------------- ### Create Replay from String Data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Parse replay data directly from a string containing the .osr file content. This is useful when the replay data is already in memory. ```python return _Unpacker(data).unpack() ``` -------------------------------- ### Write Replay to File Object Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Writes the replay data to an open file-like object. It first packs the replay data into the .osr format using the `pack` method. ```python packed = self.pack(dict_size=dict_size, mode=mode) file.write(packed) ``` -------------------------------- ### Replay Serialization Methods Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Methods to write or pack a Replay object back into the .osr file format. ```APIDOC ## Replay.write_path ### Description Writes the replay to the given path. ### Parameters #### Path Parameters - **path** (str or os.PathLike) - Required - The path to where to write the replay. ## Replay.write_file ### Description Writes the replay to an open file object. ### Parameters #### Request Body - **file** (file-like) - Required - The file object to write to. ## Replay.pack ### Description Returns the text representing this Replay in .osr format. ### Response - **str** - The text representing this Replay in .osr format. ``` -------------------------------- ### Unpack String from Replay Data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Handles unpacking strings from replay data, supporting two formats indicated by a leading byte (0x00 or 0x0b). Raises an error for unexpected formats. ```python def string_length(self, binarystream): result = 0 shift = 0 while True: byte = binarystream[self.offset] self.offset += 1 result = result |((byte & 0b01111111) << shift) if (byte & 0b10000000) == 0x00: break shift += 7 return result def unpack_string(self): if self.replay_data[self.offset] == 0x00: self.offset += 1 elif self.replay_data[self.offset] == 0x0b: self.offset += 1 string_length = self.string_length(self.replay_data) offset_end = self.offset + string_length string = self.replay_data[self.offset:offset_end].decode("utf-8") self.offset = offset_end return string else: raise ValueError("Expected the first byte of a string to be 0x00 " f"or 0x0b, but got {self.replay_data[self.offset]}") ``` -------------------------------- ### osrparse.replay Module Source: https://kszlim.github.io/osu-replay-parser/_sources/appendix.rst.txt This section details the members available within the osrparse.replay module, which likely handles the core replay parsing logic. ```APIDOC ## osrparse.replay Module ### Description Provides functionality for parsing osu! replay files. ### Members This module exposes various functions and classes for replay data manipulation. Refer to the source code for specific member details. ``` -------------------------------- ### Write Replay to File Object Source: https://kszlim.github.io/osu-replay-parser/appendix.html Use write_file to save the current Replay object's data to an open file-like object. ```python replay.write_file(file) ``` -------------------------------- ### Write Replay Data to Files or Strings Source: https://kszlim.github.io/osu-replay-parser/writing-replays.html Use these methods to export a Replay object to a file path, an open file object, or a byte string. ```python replay.write_path("path/to/new_osr.osr") # or to an opened file object with open("path/to/new_osr.osr") as f: replay.write_file(f) # or to a string packed = replay.pack() ``` -------------------------------- ### Key Enum (osu!standard) Source: https://kszlim.github.io/osu-replay-parser/appendix.html Represents a key that can be pressed during osu!standard gameplay. ```APIDOC ## osrparse.utils.Key ### Description A key that can be pressed during osu!standard gameplay - mouse 1 and 2, key 1 and 2, and smoke. ### Enum Members - **mouse1** - **mouse2** - **key1** - **key2** - **smoke** ``` -------------------------------- ### Pack Byte Data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Provides methods for packing various data types into byte format using the struct module. This is essential for serializing replay data. ```python def pack_byte(self, data): return struct.pack(">> parse_replay_data(lzma_string, decoded=True) >>> ... >>> lzma_string = lzma.decompress(lzma_string).decode("ascii") >>> parse_replay_data(lzma_string, decompressed=True) ``` |br| If ``decompressed`` is ``True``, ``decoded`` is automatically set to ``True`` as well (ie, if ``decompressed`` is ``True``, we will assume ``data_string`` is not base 64 encoded). mode: GameMode What mode to parse the replay data as. """ # assume the data is already decoded if it's been decompressed if not decoded and not decompressed: data_string = base64.b64decode(data_string) if not decompressed: data_string = lzma.decompress(data_string, format=lzma.FORMAT_AUTO) data_string = data_string.decode("ascii") (replay_data, _seed) = _Unpacker.parse_replay_data(data_string, mode) return replay_data ``` -------------------------------- ### Parse Replay Data Portion Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Parses only the replay data section (cursor movements, key presses) from a string. Options are available to handle pre-decoded or pre-decompressed data. ```python data_string, *, decoded=False, decompressed=False, mode=GameMode.STD) -> List[ReplayEvent]: ``` -------------------------------- ### parse_replay_data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Parses raw replay data strings, handling base64 decoding and lzma decompression based on the input state. ```APIDOC ## parse_replay_data ### Description Parses replay data retrieved from the osu! API v1 /get_replay endpoint. It handles the necessary decoding and decompression steps to extract replay information. ### Parameters - **data_string** (str or bytes) - Required - The replay data to parse. - **decoded** (bool) - Optional - Whether data_string has already been decoded from a base64 representation. - **decompressed** (bool) - Optional - Whether data_string has already been decompressed from lzma and decoded to ascii. If True, decoded is automatically set to True. - **mode** (GameMode) - Required - The game mode to parse the replay data as. ``` -------------------------------- ### Parse Replay Data from Decompressed LZMA String Source: https://kszlim.github.io/osu-replay-parser/parsing-replays.html If the LZMA string is already decoded and decompressed, use parse_replay_data() with the 'decompressed' parameter set to True. This bypasses both decoding and decompression steps. ```python from osrparse import parse_replay_data import base64 import lzma # or parse an already decoded and decompressed lzma string lzma_string = retrieve_from_api() lzma_string = base64.b64decode(lzma_string) lzma_string = lzma.decompress(lzma_string).decode("ascii") replay_data = parse_replay_data(lzma_string, decompressed=True) ``` -------------------------------- ### Parse Replay Data from osu! API Source: https://kszlim.github.io/osu-replay-parser/_sources/parsing-replays.rst.txt Use parse_replay_data to parse replay data from the osu! API. It can handle lzma compressed strings, base64 decoded lzma strings, or decompressed strings. ```python from osrparse import parse_replay_data import base64 import lzma lzma_string = retrieve_from_api() replay_data = parse_replay_data(lzma_string) assert isinstance(replay_data[0], ReplayEvent) # or parse an already decoded lzma string lzma_string = retrieve_from_api() lzma_string = base64.b64decode(lzma_string) replay_data = parse_replay_data(lzma_string, decoded=True) # or parse an already decoded and decompressed lzma string lzma_string = retrieve_from_api() lzma_string = base64.b64decode(lzma_string) lzma_string = lzma.decompress(lzma_string).decode("ascii") replay_data = parse_replay_data(lzma_string, decompressed=True) ``` -------------------------------- ### KeyTaiko Enum (osu!taiko) Source: https://kszlim.github.io/osu-replay-parser/appendix.html Represents a key that can be pressed during osu!taiko gameplay. ```APIDOC ## osrparse.utils.KeyTaiko ### Description A key that can be pressed during osu!taiko gameplay. ### Enum Members - **left_center** - **right_center** - **left_rim** - **right_rim** ``` -------------------------------- ### Define osu!mania Keys Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents keys that can be pressed during osu!mania gameplay. Use bitwise operations to check for pressed keys. ```python [docs]class KeyMania(IntFlag): """ A key that can be pressed during osu!mania gameplay """ K1 = 1 << 0 K2 = 1 << 1 K3 = 1 << 2 K4 = 1 << 3 K5 = 1 << 4 K6 = 1 << 5 K7 = 1 << 6 K8 = 1 << 7 K9 = 1 << 8 K10 = 1 << 9 K11 = 1 << 10 K12 = 1 << 11 K13 = 1 << 12 K14 = 1 << 13 K15 = 1 << 14 K16 = 1 << 15 K17 = 1 << 16 K18 = 1 << 17 ``` -------------------------------- ### LifeBarState Class Source: https://kszlim.github.io/osu-replay-parser/appendix.html Represents a state of the lifebar shown on the results screen. ```APIDOC ## osrparse.utils.LifeBarState ### Description A state of the lifebar shown on the results screen, at a particular point in time. ### Attributes - **time** (int) - The time, in ms, this life bar state corresponds to in the replay. The time since the previous event (ie frame). - **life** (float) - The amount of life at this life bar state. ``` -------------------------------- ### Pack Life Bar Graph Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Serializes the life bar graph data into a string format (time|life,). It handles float and integer life values and packs the resulting string. ```python def pack_life_bar(self): data = "" if self.replay.life_bar_graph is None: return self.pack_string(data) for state in self.replay.life_bar_graph: life = state.life # store 0 or 1 instead of 0.0 or 1.0 if int(life) == life: life = int(state.life) data += f"{state.time}|{life}," return self.pack_string(data) ``` -------------------------------- ### Replay Event (Mania) Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents a single frame in an osu!mania replay. ```APIDOC ## Dataclass ReplayEventMania ### Description A single frame in an osu!mania replay. ### Attributes - **time_delta** (int) - The time since the previous event (ie frame). - **keys** (KeyMania) - The keys pressed. ``` -------------------------------- ### KeyMania Enum (osu!mania) Source: https://kszlim.github.io/osu-replay-parser/appendix.html Represents a key that can be pressed during osu!mania gameplay. ```APIDOC ## osrparse.utils.KeyMania ### Description A key that can be pressed during osu!mania gameplay. ### Enum Members - **key1** - **key2** - **key3** - **key4** - **key5** - **key6** - **key7** - **key8** - **key9** - **key10** ``` -------------------------------- ### osu!taiko Replay Event Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents a single frame in an osu!taiko replay. Includes an unknown 'x' value and keys pressed. ```python [docs]@dataclass class ReplayEventTaiko(ReplayEvent): """ A single frame in an osu!taiko replay. Attributes ---------- time_delta: int The time since the previous event (ie frame). x: int Unknown what this represents. Always one of 0, 320, or 640, depending on ``keys``. keys: KeyTaiko The keys pressed. """ # we have no idea what this is supposed to represent. It's always one of 0, # 320, or 640, depending on `keys`. Leaving untouched for now. x: int keys: KeyTaiko ``` -------------------------------- ### Base Replay Event Structure Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Base class for a replay event (frame). Contains the time delta since the previous event. This is a base class and should not be instantiated directly. ```python [docs]@dataclass class ReplayEvent: """ Base class for an event (ie a frame) in a replay. Attributes ---------- time_delta: int The time since the previous event (ie frame). """ time_delta: int ``` -------------------------------- ### Define osu!taiko Keys Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents keys that can be pressed during osu!taiko gameplay. Use bitwise operations to check for pressed keys. ```python [docs]class KeyTaiko(IntFlag): """ A key that can be pressed during osu!taiko gameplay. """ LEFT_DON = 1 << 0 LEFT_KAT = 1 << 1 RIGHT_DON = 1 << 2 RIGHT_KAT = 1 << 3 ``` -------------------------------- ### Unpack LZMA Compressed Play Data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Decompresses and parses LZMA-compressed play data from the replay. Handles ASCII decoding and calls a static method to parse the event data. ```python def unpack_play_data(self, mode): replay_length = self.unpack_once("i") offset_end = self.offset + replay_length data = self.replay_data[self.offset:offset_end] data = lzma.decompress(data, format=lzma.FORMAT_AUTO) data = data.decode("ascii") (replay_data, rng_seed) = self.parse_replay_data(data, mode) self.offset = offset_end return (replay_data, rng_seed) ``` -------------------------------- ### Parse Replay Data String Source: https://kszlim.github.io/osu-replay-parser/appendix.html Use parse_replay_data to parse the replay data portion from a string. This is useful for data obtained from APIs. ```python osrparse.replay.parse_replay_data(data_string, decoded=False, decompressed=False, mode=GameMode.STD) ``` -------------------------------- ### osu!mania Replay Event Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents a single frame in an osu!mania replay. Includes the keys pressed. ```python [docs]@dataclass class ReplayEventMania(ReplayEvent): """ A single frame in an osu!mania replay. Attributes ---------- time_delta: int The time since the previous event (ie frame). keys: KeyMania The keys pressed. """ keys: KeyMania ``` -------------------------------- ### Mod Enum Source: https://kszlim.github.io/osu-replay-parser/appendix.html Represents an osu! mod or a combination of mods. ```APIDOC ## osrparse.utils.Mod ### Description An osu! mod, or combination of mods. ### Enum Members - **NoFail** - **Easy** - **NoVideo** - **Hidden** - **HardRock** - **SuddenDeath** - **DoubleTime** - **Relax** - **HalfTime** - **Daycore** - **Flashlight** - **SpunOut** - **Auto** - **Perfect** - **KeyMod** - **V2** - **ScoreIncrease** ``` -------------------------------- ### Parse Decompressed Replay Data Source: https://kszlim.github.io/osu-replay-parser/appendix.html When replay data is already decompressed and decoded (e.g., from an API response), use decompressed=True with parse_replay_data. ```python osrparse.replay.parse_replay_data(lzma_string, decompressed=True) ``` -------------------------------- ### Parse Replay Event Data Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Parses a string of replay events into a list of ReplayEvent objects, specific to the game mode. Also extracts the RNG seed if present. ```python @staticmethod def parse_replay_data(replay_data_str, mode): # remove trailing comma to make splitting easier replay_data_str = replay_data_str[:-1] events = [event.split('|') for event in replay_data_str.split(',')] rng_seed = None play_data = [] for event in events: time_delta = int(event[0]) x = event[1] y = event[2] keys = int(event[3]) if time_delta == -12345 and event == events[-1]: rng_seed = keys continue if mode is GameMode.STD: keys = Key(keys) event = ReplayEventOsu(time_delta, float(x), float(y), keys) if mode is GameMode.TAIKO: event = ReplayEventTaiko(time_delta, int(x), KeyTaiko(keys)) if mode is GameMode.CTB: event = ReplayEventCatch(time_delta, float(x), int(keys) == 1) if mode is GameMode.MANIA: event = ReplayEventMania(time_delta, KeyMania(keys)) play_data.append(event) return (play_data, rng_seed) ``` -------------------------------- ### Parse Replay Data from LZMA String Source: https://kszlim.github.io/osu-replay-parser/parsing-replays.html Use parse_replay_data() to parse the replay data portion from an osu! API v1 response. This function handles LZMA compressed data. ```python from osrparse import parse_replay_data import base64 import lzma lzma_string = retrieve_from_api() replay_data = parse_replay_data(lzma_string) ``` -------------------------------- ### Unpack Single Value with Struct Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Unpacks a single value from the replay data using a specified struct format string. Always uses little-endian byte order. ```python def unpack_once(self, specifier): # always use little endian specifier = f"<{specifier}" unpacked = struct.unpack_from(specifier, self.replay_data, self.offset) self.offset += struct.calcsize(specifier) # `struct.unpack_from` always returns a tuple, even if there's only one # element return unpacked[0] ``` -------------------------------- ### Pack ULEB128 Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Encodes an integer into the ULEB128 format, a variable-length encoding scheme. This is used for packing string lengths. ```python def pack_ULEB128(self, data): # https://github.com/mohanson/leb128 r, i = [], len(data) while True: byte = i & 0x7f i = i >> 7 if (i == 0 and byte & 0x40 == 0) or (i == -1 and byte & 0x40 != 0): r.append(byte) return b"".join(map(self.pack_byte, r)) r.append(0x80 | byte) ``` -------------------------------- ### Unpack Life Bar States Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/replay.html Unpacks the life bar states from a string, splitting it into individual states and parsing each into a LifeBarState object. Returns None if the string is empty. ```python def unpack_life_bar(self): life_bar = self.unpack_string() if not life_bar: return None # remove trailing comma to make splitting easier life_bar = life_bar[:-1] states = [state.split("|") for state in life_bar.split(",")] return [LifeBarState(int(s[0]), float(s[1])) for s in states] ``` -------------------------------- ### Define osu! Game Modes Source: https://kszlim.github.io/osu-replay-parser/_modules/osrparse/utils.html Represents the different game modes in osu!. Use this enum to identify the game mode of a replay. ```python from enum import Enum, IntFlag from dataclasses import dataclass [docs]class GameMode(Enum): """ An osu! game mode. """ STD = 0 TAIKO = 1 CTB = 2 MANIA = 3 ```