Skip to content

Commit e900a8b

Browse files
committed
Rework the pid assignment and event mapping (again).
1 parent bd1e7d4 commit e900a8b

File tree

3 files changed

+60
-87
lines changed

3 files changed

+60
-87
lines changed

sc2reader/events.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,22 @@ def __init__(self, frame, pid):
1616
# self.time = Length(seconds=self.second)
1717

1818
def load_context(self, replay):
19-
if self.pid < len(replay.people):
20-
self.player = replay.people[self.pid]
21-
elif self.pid != 16:
22-
self.logger.error("Bad pid ({0}) for event {1} at {2}.".format(self.pid, self.__class__, Length(seconds=self.second)))
23-
else:
24-
pass # This is a global event
19+
if replay.expansion == 'WoL' or replay.build < 24247:
20+
if self.pid <= len(replay.people):
21+
self.player = replay.person[self.pid]
22+
elif self.pid != 16:
23+
self.logger.error("Bad pid ({0}) for event {1} at {2}.".format(self.pid, self.__class__, Length(seconds=self.second)))
24+
else:
25+
pass # This is a global event
26+
27+
elif replay.expansion == 'HotS':
28+
if self.pid < len(replay.clients):
29+
self.player = replay.client[self.pid]
30+
elif self.pid != 16:
31+
self.logger.error("Bad pid ({0}) for event {1} at {2}.".format(self.pid, self.__class__, Length(seconds=self.second)))
32+
else:
33+
pass # This is a global event
34+
2535

2636
def _str_prefix(self):
2737
player_name = self.player.name if getattr(self,'pid', 16)!=16 else "Global"

sc2reader/readers.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ def __call__(self, data, replay):
105105
data.read_byte(),
106106
data.read(4).strip('\00 ')[::-1]
107107
]
108-
109-
if info[2]!=16: info[2]-=1 # Convert from 1-offset to 0-offset
110-
#print hex(info[1]), "P"+str(info[2]), info[3]
111108
attribute_events.append(Attribute(info))
112109

113110
return attribute_events
@@ -196,7 +193,6 @@ class DetailsReader_Beta_24764(DetailsReader_Beta):
196193
PlayerData = namedtuple('PlayerData',['name','bnet','race','color','unknown1','unknown2','handicap','unknown3','result','unknown4'])
197194

198195
class MessageEventsReader_Base(Reader):
199-
POFFSET=-1
200196
TARGET_BITS=3
201197
def __call__(self, data, replay):
202198
# The replay.message.events file is a single long list containing three
@@ -211,7 +207,6 @@ def __call__(self, data, replay):
211207
# All the element types share the same time, pid, flags header.
212208
frame += data.read_timestamp()
213209
pid = data.read_bits(5)
214-
if pid != 16: pid+=self.POFFSET
215210
t = data.read_bits(3)
216211
flags = data.read_byte()
217212

@@ -237,7 +232,6 @@ def __call__(self, data, replay):
237232
return AttributeDict(pings=pings, messages=messages, packets=packets)
238233

239234
class MessageEventsReader_Beta_24247(MessageEventsReader_Base):
240-
POFFSET=0
241235
TARGET_BITS=4
242236

243237
class GameEventsReader_Base(object):
@@ -246,7 +240,6 @@ class GameEventsReader_Base(object):
246240
ABILITY_TEAM_FLAG = False
247241
UNIT_INDEX_BITS = 8
248242
HOTKEY_OVERLAY = 0
249-
POFFSET = -1
250243

251244
def __init__(self):
252245
self.EVENT_DISPATCH = {
@@ -281,7 +274,6 @@ def __call__(self, data, replay):
281274
while event_start != data_length:
282275
fstamp += read_timestamp()
283276
pid = read_bits(5)
284-
if pid != 16: pid+= self.POFFSET
285277
event_type = read_bits(7)
286278

287279
# Check for a lookup
@@ -598,6 +590,3 @@ def player_selection_event(self, data, fstamp, pid, event_type):
598590

599591
class GameEventsReader_Beta_23925(GameEventsReader_Beta):
600592
PLAYER_JOIN_FLAGS = 32
601-
602-
class GameEventsReader_Beta_24247(GameEventsReader_Beta_23925):
603-
POFFSET = 0

sc2reader/resources.py

Lines changed: 44 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -335,27 +335,22 @@ def load_players(self):
335335
if 'replay.initData' not in self.raw_data:
336336
return
337337

338-
# 1. pids are in lobby join order, use initData.player_names
339-
# 2. use the name to get the player_data index
340-
# 2a. if observer, save pid+name for later
341-
# 3. use the player_data index as the attrib_data index...?
342-
# 4. use the player_data and attribute_data to load the player
343-
# 5. after loop, load the computer players and (optionally) their attributes
344-
# 6. then load the observer pid,name using attributes if available
338+
self.clients = list()
339+
self.client = dict()
340+
341+
def createObserver(pid, name, attributes):
342+
# TODO: Make use of that attributes, new in HotS
343+
observer = Observer(pid, name)
344+
return observer
345+
345346
def createPlayer(pid, pdata, attributes):
346-
# General information re: each player comes from the following files
347-
# * replay.initData
348-
# * replay.details
349-
# * replay.attribute.events
350-
#
351-
# TODO: recognize current locale and use that instead of western
352-
# TODO: fill in the LOCALIZED_RACES table
353-
player = Player(pid,pdata.name)
354-
355-
# Cross reference the player and team lookups
356-
# TODO: Players without attribute events, where do we get the team info?
357-
# print pdata.name, attributes, pdata
358-
team_number = attributes.get('Teams'+self.type,0)
347+
# make sure to strip the clan tag out of the name
348+
name = pdata.name.split("]")[-1]
349+
player = Player(pid, name)
350+
351+
# In some beta patches attribute information is missing
352+
# Just assign them to team 2 to keep the issue from being fatal
353+
team_number = attributes.get('Teams'+self.type,2)
359354
if not team_number in self.team:
360355
self.team[team_number] = Team(team_number)
361356
self.teams.append(self.team[team_number])
@@ -368,70 +363,50 @@ def createPlayer(pid, pdata, attributes):
368363
self.winner = player.team
369364
elif pdata.result == 2:
370365
player.team.result = "Loss"
366+
else:
367+
pass # We don't need to do anything here?
371368

372369
player.pick_race = attributes.get('Race','Unknown')
373370
player.play_race = LOCALIZED_RACES.get(pdata.race, pdata.race)
374371
player.difficulty = attributes.get('Difficulty','Unknown')
375372
player.is_human = (attributes.get('Player Type','Computer') == 'Human')
376373
player.uid = pdata.bnet.uid
377374
player.subregion = pdata.bnet.subregion
375+
player.gateway = {0:'', 1:'us',2:'eu',3:'kr',6:'sea', 98:'xx'}[pdata.bnet.unknown1] # actually is gateway!!!
378376
player.handicap = pdata.handicap
379-
380-
# We need initData for the gateway portion of the url!
381-
if self.gateway:
382-
player.gateway = self.gateway
383-
if player.is_human and player.subregion:
384-
player.region = REGIONS[self.gateway].get(player.subregion, 'Unknown')
385-
386-
# Conversion instructions to the new color object:
387-
# color_rgba is the color object itself
388-
# color_hex is color.hex
389-
# color is str(color)
390377
player.color = utils.Color(**pdata.color._asdict())
378+
return player
391379

392-
# Each player can be referenced in a number of different ways,
393-
# primarily for convenience of access in any given situation.
394-
self.people.append(player)
380+
381+
pid = 0
382+
clients = self.raw_data['replay.initData'].player_names
383+
for index, pdata in enumerate(self.raw_data['replay.details'].players):
384+
pid += 1
385+
attributes = self.attributes.get(pid, dict())
386+
player = createPlayer(pid, pdata, attributes)
387+
self.player[pid] = player
395388
self.players.append(player)
396389
self.player[pid] = player
390+
self.people.append(player)
397391
self.person[pid] = player
398392

399-
def createObserver(pid, name, attributes):
400-
observer = Observer(pid,name)
401-
self.observers.append(observer)
402-
self.people.append(observer)
403-
self.person[pid] = observer
404-
405-
observer_data = list()
406-
unassigned_player_data = collections.OrderedDict((p.name, (idx,p)) for idx, p in enumerate(self.raw_data['replay.details'].players))
407-
try:
408-
for pid, name in enumerate(self.raw_data['replay.initData'].player_names):
409-
if name in unassigned_player_data:
410-
idx, pdata = unassigned_player_data[name]
411-
attributes = self.attributes.get(idx,dict())
412-
createPlayer(pid, pdata, attributes)
413-
del unassigned_player_data[name]
414-
else:
415-
observer_data.append((pid,name))
416-
417-
comp_start_id = len(self.raw_data['replay.initData'].player_names)
418-
for name, (idx,pdata) in unassigned_player_data.items():
419-
attributes = self.attributes.get(idx,dict())
420-
createPlayer(comp_start_id, pdata, attributes)
421-
comp_start_id+=1
422-
423-
obs_start_idx = len(self.raw_data['replay.details'].players)
424-
for pid, name in observer_data:
425-
attributes = self.attributes.get(obs_start_idx,dict())
426-
createObserver(pid, name, attributes)
427-
obs_start_idx+=1
428-
except:
429-
print unassigned_player_data
430-
print self.raw_data['replay.initData'].player_names
431-
raise
393+
for cid, name in enumerate(clients):
394+
if name not in self.player._key_map:
395+
pid += 1
396+
attributes = self.attributes.get(pid, dict())
397+
client = createObserver(pid, name, attributes)
398+
self.observers.append(client)
399+
self.people.append(client)
400+
self.person[pid] = client
401+
else:
402+
client = self.player.name(name)
432403

404+
client.cid = cid
405+
self.clients.append(client)
406+
self.client[cid] = client
433407

434-
self.humans = filter(lambda p: p.is_human, self.people)
408+
# replay.clients replaces replay.humans
409+
self.humans = self.clients
435410

436411
#Create an store an ordered lineup string
437412
for team in self.teams:
@@ -573,8 +548,7 @@ def register_default_readers(self):
573548
self.register_reader('replay.game.events', readers.GameEventsReader_19595(), lambda r: 19595 <= r.build < 22612)
574549
self.register_reader('replay.game.events', readers.GameEventsReader_22612(), lambda r: 22612 <= r.build and r.expansion=='WoL')
575550
self.register_reader('replay.game.events', readers.GameEventsReader_Beta(), lambda r: r.expansion=='HotS' and r.build < 23925)
576-
self.register_reader('replay.game.events', readers.GameEventsReader_Beta_23925(), lambda r: r.expansion=='HotS' and 23925 <= r.build < 24247)
577-
self.register_reader('replay.game.events', readers.GameEventsReader_Beta_24247(), lambda r: r.expansion=='HotS' and 24247 <= r.build )
551+
self.register_reader('replay.game.events', readers.GameEventsReader_Beta_23925(), lambda r: r.expansion=='HotS' and 23925 <= r.build)
578552

579553

580554
def register_default_datapacks(self):

0 commit comments

Comments
 (0)