Skip to content

Commit a0a2133

Browse files
committed
Don't crash the ContextLoader if we are missing a datapack.
1 parent ca1cfc8 commit a0a2133

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

sc2reader/engine/plugins/context.py

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010
class ContextLoader(object):
1111

1212
def handleInitGame(self, event, replay):
13-
if not replay.datapack:
14-
raise ValueError("ContextLoader requires a datapack to run")
15-
1613
replay.units = set()
1714
replay.unit = dict()
1815

@@ -23,6 +20,9 @@ def handleMessageEvent(self, event, replay):
2320
self.load_message_game_player(event, replay)
2421

2522
def handleAbilityEvent(self, event, replay):
23+
if not replay.datapack:
24+
return
25+
2626
if event.ability_id not in replay.datapack.abilities:
2727
if not getattr(replay, 'marked_error', None):
2828
replay.marked_error = True
@@ -43,6 +43,9 @@ def handleAbilityEvent(self, event, replay):
4343
self.logger.error("Other unit {0} not found".format(event.other_unit_id))
4444

4545
def handleTargetAbilityEvent(self, event, replay):
46+
if not replay.datapack:
47+
return
48+
4649
if event.target_unit_id in replay.objects:
4750
event.target = replay.objects[event.target_unit_id]
4851
if not event.target.is_type(event.target_unit_type):
@@ -53,6 +56,9 @@ def handleTargetAbilityEvent(self, event, replay):
5356
replay.objects[event.target_unit_id] = unit
5457

5558
def handleSelectionEvent(self, event, replay):
59+
if not replay.datapack:
60+
return
61+
5662
units = list()
5763
for (unit_id, unit_type, subgroup, intra_subgroup) in event.new_unit_info:
5864
# If we don't have access to tracker events, use selection events to create
@@ -92,6 +98,9 @@ def handleUnitBornEvent(self, event, replay):
9298
self.load_tracker_upkeeper(event, replay)
9399
self.load_tracker_controller(event, replay)
94100

101+
if not replay.datapack:
102+
return
103+
95104
if event.unit_id in replay.objects:
96105
# This can happen because game events are done first
97106
event.unit = replay.objects[event.unit_id]
@@ -120,37 +129,33 @@ def handleUnitDiedEvent(self, event, replay):
120129
if event.unit_id_index in replay.active_units:
121130
del replay.active_units[event.unit_id_index]
122131
else:
123-
pass # print("Unable to delete unit, not index not active: {0}".format(event.unit_id_index))
132+
self.logger.error("Unable to delete unit index {0} at {1} [{2}], index not active.".format(event.killer_pid, Length(seconds=event.second), event.frame))
124133
else:
125-
pass # print("Unit died before it was born!")
134+
self.logger.error("Unit {0} died at {1} [{2}] before it was born!".format(event.unit_id, Length(seconds=event.second), event.frame))
126135

127136
if event.killer_pid in replay.player:
128137
event.killer = replay.player[event.killer_pid]
129138
if event.unit:
130139
event.unit.killed_by = event.killer
131140
event.killer.killed_units.append(event.unit)
132141
elif event.killer_pid:
133-
pass # print("Unknown killer pid: {0}".format(event.killer_pid))
142+
self.logger.error("Unknown killer pid {0} at {1} [{2}]".format(event.killer_pid, Length(seconds=event.second), event.frame))
134143

135144
def handleUnitOwnerChangeEvent(self, event, replay):
136-
if event.control_pid in replay.player:
137-
event.unit_controller = replay.player[event.control_pid]
138-
elif event.control_pid != 0:
139-
pass # print("Unknown controller pid: {0}".format(event.control_pid))
145+
self.load_tracker_controller(event, replay)
146+
self.load_tracker_upkeeper(event, replay)
140147

141-
if event.upkeep_pid in replay.player:
142-
event.unit_upkeeper = replay.player[event.upkeep_pid]
143-
elif event.upkeep_pid != 0:
144-
pass # print("Unknown upkeep pid: {0}".format(event.upkeep_pid))
148+
if not replay.datapack:
149+
return
145150

146151
if event.unit_id in replay.objects:
147152
event.unit = replay.objects[event.unit_id]
148153
else:
149-
pass # print("Unit owner changed before it was born!")
154+
self.logger.error("Unit {0} owner changed at {1} [{2}] before it was born!".format(event.unit_id, Length(seconds=event.second), event.frame))
150155

151156
if event.unit_upkeeper:
152157
if event.unit.owner:
153-
event.unit.owner.units.remove(unit)
158+
event.unit.owner.units.remove(event.unit)
154159
event.unit.owner = event.unit_upkeeper
155160
event.unit_upkeeper.units.append(event.unit)
156161

@@ -162,7 +167,7 @@ def handleUnitTypeChangeEvent(self, event, replay):
162167
event.unit = replay.objects[event.unit_id]
163168
replay.datapack.change_type(event.unit, event.unit_type_name, event.frame)
164169
else:
165-
pass # print("Unit type changed before it was born!")
170+
self.logger.error("Unit {0} type changed at {1} [{2}] before it was born!".format(event.unit_id, Length(seconds=event.second)))
166171

167172
def handleUpgradeCompleteEvent(self, event, replay):
168173
self.load_tracker_player(event, replay)
@@ -173,11 +178,11 @@ def handleUnitInitEvent(self, event, replay):
173178
self.load_tracker_upkeeper(event, replay)
174179
self.load_tracker_controller(event, replay)
175180

181+
if not replay.datapack:
182+
return
183+
176184
if event.unit_id in replay.objects:
177-
# This can happen because game events are done first
178185
event.unit = replay.objects[event.unit_id]
179-
if not event.unit.is_type(event.unit_type_name):
180-
pass # print("CONFLICT {0} <-_-> {1}".format(event.unit._type_class.str_id, event.unit_type_name))
181186
else:
182187
# TODO: How to tell if something is hallucination?
183188
event.unit = replay.datapack.create_unit(event.unit_id, event.unit_type_name, 0, event.frame)
@@ -192,54 +197,60 @@ def handleUnitInitEvent(self, event, replay):
192197
event.unit.owner.units.append(event.unit)
193198

194199
def handleUnitDoneEvent(self, event, replay):
200+
if not replay.datapack:
201+
return
202+
195203
if event.unit_id in replay.objects:
196204
event.unit = replay.objects[event.unit_id]
197205
event.unit.finished_at = event.frame
198206
else:
199-
pass # print("Unit done before it was started!")
207+
self.logger.error("Unit {0} done at {1} [{2}] before it was started!".format(event.killer_pid, Length(seconds=event.second), event.frame))
200208

201209
def handleUnitPositionsEvent(self, event, replay):
210+
if not replay.datapack:
211+
return
212+
202213
for unit_index, (x, y) in event.positions:
203214
if unit_index in replay.active_units:
204215
unit = replay.active_units[unit_index]
205216
unit.location = (x, y)
206217
event.units[unit] = unit.location
207218
else:
208-
pass # print("Unit moved that doesn't exist!")
219+
self.logger.error("Unit at active_unit index {0} moved at {1} [{2}] but it doesn't exist!".format(event.killer_pid, Length(seconds=event.second), event.frame))
209220

210221
def load_message_game_player(self, event, replay):
211222
if replay.versions[1] == 1 or (replay.versions[1] == 2 and replay.build < 24247):
212-
if event.pid <= len(replay.people):
213-
event.player = replay.person[event.pid]
223+
if event.pid in replay.entity:
224+
event.player = replay.entity[event.pid]
214225
event.player.events.append(event)
215226
elif event.pid != 16:
216-
self.logger.error("Bad pid ({0}) for event {1} at {2}.".format(event.pid, event.__class__, Length(seconds=event.second)))
227+
self.logger.error("Bad pid ({0}) for event {1} at {2} [{3}].".format(event.pid, event.__class__, Length(seconds=event.second), event.frame))
217228
else:
218229
pass # This is a global event
219230

220-
else:
221-
if event.pid < len(replay.clients):
222-
event.player = replay.client[event.pid]
231+
else: # Now event.pid is actually a user id for human entities
232+
if event.pid < len(replay.humans):
233+
event.player = replay.human[event.pid]
223234
event.player.events.append(event)
224235
elif event.pid != 16:
225-
self.logger.error("Bad pid ({0}) for event {1} at {2}.".format(event.pid, event.__class__, Length(seconds=event.second)))
236+
self.logger.error("Bad pid ({0}) for event {1} at {2} [{3}].".format(event.pid, event.__class__, Length(seconds=event.second), event.frames))
226237
else:
227238
pass # This is a global event
228239

229240
def load_tracker_player(self, event, replay):
230241
if event.pid in replay.player:
231242
event.player = replay.player[event.pid]
232243
else:
233-
pass # print("Unknown upgrade pid: {0}".format(event.pid))
244+
self.logger.error("Bad pid ({0}) for event {1} at {2} [{3}].".format(event.pid, event.__class__, Length(seconds=event.second), event.frame))
234245

235246
def load_tracker_upkeeper(self, event, replay):
236247
if event.upkeep_pid in replay.player:
237248
event.unit_upkeeper = replay.player[event.upkeep_pid]
238249
elif event.upkeep_pid != 0:
239-
pass # print("Unknown upkeep pid: {0}".format(event.upkeep_pid))
250+
self.logger.error("Bad upkeep_pid ({0}) for event {1} at {2} [{3}].".format(event.upkeep_pid, event.__class__, Length(seconds=event.second), event.frame))
240251

241252
def load_tracker_controller(self, event, replay):
242253
if event.control_pid in replay.player:
243254
event.unit_controller = replay.player[event.control_pid]
244255
elif event.control_pid != 0:
245-
pass # print("Unknown controller pid: {0}".format(event.control_pid))
256+
self.logger.error("Bad control_pid ({0}) for event {1} at {2} [{3}].".format(event.control_pid, event.__class__, Length(seconds=event.second), event.frame))

sc2reader/events/tracker.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class TrackerEvent(Event):
1313
def __init__(self, frames):
1414
#: The frame of the game this event was applied
1515
self.frame = frames
16+
self.second = frames >> 4
1617

1718
def load_context(self, replay):
1819
pass

0 commit comments

Comments
 (0)