diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 9ee1965f..f3d95ef3 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,7 @@ CHANGELOG 0.7.0 - --------------------------- +* Added replay.resume_from_replay flag. See replay.resume_user_info for additional info. * PacketEvent is now ProgressEvent. * SetToHotkeyEvent is now SetControlGroupEvent. * AddToHotkeyEvent is now AddToControlGroupEvent. diff --git a/sc2reader/engine/plugins/context.py b/sc2reader/engine/plugins/context.py index 099569a0..feb013c5 100644 --- a/sc2reader/engine/plugins/context.py +++ b/sc2reader/engine/plugins/context.py @@ -99,6 +99,11 @@ def handleResourceTradeEvent(self, event, replay): event.sender = event.player event.recipient = replay.players[event.recipient_id] + def handleHijackReplayGameEvent(self, event, replay): + replay.resume_from_replay = True + replay.resume_method = event.method + replay.resume_user_info = event.user_infos + def handlePlayerStatsEvent(self, event, replay): self.load_tracker_player(event, replay) diff --git a/sc2reader/events/game.py b/sc2reader/events/game.py index 584f8b1a..4f9d6735 100644 --- a/sc2reader/events/game.py +++ b/sc2reader/events/game.py @@ -581,3 +581,17 @@ def __init__(self, frame, pid, data): #: The id of the request being cancelled self.request_id = data['request_id'] + + +class HijackReplayGameEvent(GameEvent): + """ + Generated when players take over from a replay. + """ + def __init__(self, frame, pid, data): + super(HijackReplayGameEvent, self).__init__(frame, pid) + + #: The method used. Not sure what 0/1 represent + self.method = data['method'] + + #: Information on the users hijacking the game + self.user_infos = data['user_infos'] diff --git a/sc2reader/readers.py b/sc2reader/readers.py index 61f8d928..ed9244ce 100644 --- a/sc2reader/readers.py +++ b/sc2reader/readers.py @@ -1326,7 +1326,7 @@ def __init__(self): 21: (None, self.save_game_event), # New 22: (None, self.save_game_done_event), # Override 23: (None, self.load_game_done_event), # Override - 43: (None, self.hijack_replay_game_event), # New + 43: (HijackReplayGameEvent, self.hijack_replay_game_event), # New 62: (None, self.trigger_target_mode_update_event), # New 101: (PlayerLeaveEvent, self.game_user_leave_event), # New 102: (None, self.game_user_join_event), # New @@ -1356,7 +1356,7 @@ def load_game_done_event(self, data): def hijack_replay_game_event(self, data): return dict( user_infos=[dict( - game_unit_id=data.read_bits(4), + game_user_id=data.read_bits(4), observe=data.read_bits(2), name=data.read_aligned_string(data.read_uint8()), toon_handle=data.read_aligned_string(data.read_bits(7)) if data.read_bool() else None, diff --git a/sc2reader/resources.py b/sc2reader/resources.py index f9eeceaa..d9f8c7d4 100644 --- a/sc2reader/resources.py +++ b/sc2reader/resources.py @@ -184,6 +184,16 @@ class Replay(Resource): #: SC2 Expansion. One of 'WoL', 'HotS' expasion = str() + #: True of the game was resumed from a replay + resume_from_replay = False + + #: A flag marking which method was used to resume from replay. Unknown interpretation. + resume_method = None + + #: Lists info for each user that is resuming from replay. + resume_user_info = None + + def __init__(self, replay_file, filename=None, load_level=4, engine=sc2reader.engine, **options): super(Replay, self).__init__(replay_file, filename, **options) self.datapack = None diff --git a/test_replays/test_all.py b/test_replays/test_all.py index dbbfd157..5040b4b9 100644 --- a/test_replays/test_all.py +++ b/test_replays/test_all.py @@ -227,6 +227,8 @@ def test_oracle_parsing(self): def test_resume_from_replay(self): replay = sc2reader.load_replay("test_replays/2.0.3.24764/resume_from_replay.SC2Replay") + self.assertTrue(replay.resume_from_replay) + self.assertEqual(replay.resume_method, 0) def test_clan_players(self): replay = sc2reader.load_replay("test_replays/2.0.4.24944/Lunar Colony V.SC2Replay")