Skip to content

Commit

Permalink
Merge pull request #26 from kszlim/old-replayid
Browse files Browse the repository at this point in the history
Fall back to parsing replay id as a short on error
  • Loading branch information
tybug authored Apr 12, 2021
2 parents 40e8ec6 + 28f57eb commit 9f5c25f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
27 changes: 21 additions & 6 deletions osrparse/replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

from osrparse.enums import Mod, GameMode

# the first build with rng seed value added as the last frame in the lzma data.
VERSION_THRESHOLD = 20130319

class ReplayEvent():
def __init__(self, time_since_previous_action: int, x: float, y: float, keys_pressed: int):
self.time_since_previous_action = time_since_previous_action
Expand All @@ -28,6 +25,8 @@ def __hash__(self):
return hash((self.time_since_previous_action, self.x, self.y, self.keys_pressed))

class Replay():
# first version with rng seed value added as the last frame in the lzma data
LAST_FRAME_SEED_VERSION = 20130319
_BYTE = 1
_SHORT = 2
_INT = 4
Expand Down Expand Up @@ -143,10 +142,11 @@ def _parse_play_data(self, replay_data):
self.play_data = [ReplayEvent(int(event[0]), float(event[1]), float(event[2]), int(event[3])) for event in events]
self.offset = offset_end

if self.game_version >= VERSION_THRESHOLD and self.play_data:
if self.game_version >= self.LAST_FRAME_SEED_VERSION and self.play_data:
if self.play_data[-1].time_since_previous_action != -12345:
print("The RNG seed value was expected in the last frame, but was not found. "
"\nGame Version: {}, version threshold: {}, replay hash: {}, mode: {}".format(self.game_version, VERSION_THRESHOLD, self.replay_hash, "osr"))
f"\nGame Version: {self.game_version}, version threshold: "
f"{self.LAST_FRAME_SEED_VERSION}, replay hash: {self.replay_hash}")
else:
del self.play_data[-1]

Expand All @@ -165,4 +165,19 @@ def data_from_lmza(self, lzma_string, decompressed_lzma):

def _parse_replay_id(self, replay_data):
format_specifier = "<q"
self.replay_id = struct.unpack_from(format_specifier, replay_data, self.offset)[0]
try:
replay_id = struct.unpack_from(format_specifier, replay_data, self.offset)
# old replays had replay_id stored as a short (4 bytes) instead of a
# long (8 bytes), so fall back to short if necessary.
# lazer checks against the gameversion before trying to parse as a
# short, but there may be some weirdness with replays that were set
# during this time but downloaded later having actually correct (long)
# replay_ids, since they were likely manually migrated at some point
# after the switch to long took place.
# See:
# https://github.com/ppy/osu/blob/84e1ff79a0736aa6c7a44804b585ab1c54a84399/
# osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs#L78-L81
except struct.error:
format_specifier = "<l"
replay_id = struct.unpack_from(format_specifier, replay_data, self.offset)
self.replay_id = replay_id[0]
Binary file added tests/resources/replay_old_replayid.osr
Binary file not shown.
8 changes: 8 additions & 0 deletions tests/test_replay.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def setUpClass(cls):
data = f.read()
cls._replays = [parse_replay(data, pure_lzma=False), parse_replay_file(replay1_path)]
cls._combination_replay = parse_replay_file(RES / "replay2.osr")
cls._old_replayid_replay = parse_replay_file(RES / "replay_old_replayid.osr")

def test_replay_mode(self):
for replay in self._replays:
Expand Down Expand Up @@ -64,3 +65,10 @@ def test_play_data(self):
for replay in self._replays:
self.assertIsInstance(replay.play_data[0], ReplayEvent, "Replay data is wrong")
self.assertEqual(len(replay.play_data), 17500, "Replay data is wrong")

def test_replay_id(self):
for replay in self._replays:
self.assertEqual(replay.replay_id, 1040219800)
# old replays had game_version stored as a short, we want to make sure
# we can parse it properly instead of erroring
self.assertEqual(self._old_replayid_replay.replay_id, 1127598189)

0 comments on commit 9f5c25f

Please sign in to comment.