Skip to content

Commit 30c4f21

Browse files
committed
Change the Reader call interface to use __call__.
Also apply a general cleanup of the processor code.
1 parent afa6e6c commit 30c4f21

File tree

3 files changed

+36
-45
lines changed

3 files changed

+36
-45
lines changed

sc2reader/__init__.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,20 @@ def read(self, location):
3333
tolist = lambda x: [x] if isinstance(x,Replay) else x
3434
return sum(map(tolist,(read(x) for x in os.listdir(location))),[])
3535

36-
else:
37-
with open(location) as replay_file:
38-
replay = Replay(replay_file,**self.options.copy())
39-
archive = mpyq.MPQArchive(location,listfile=False)
36+
with open(location) as replay_file:
37+
replay = Replay(replay_file,**self.options.copy())
38+
archive = mpyq.MPQArchive(location,listfile=False)
4039

41-
for file in self.files:
42-
buffer = ReplayBuffer(archive.read_file(file))
43-
READERS[replay.build][file].read(buffer,replay)
40+
for file in self.files:
41+
buffer = ReplayBuffer(archive.read_file(file))
42+
read = config.readers[replay.build][file]
43+
read(buffer,replay)
4444

45-
#Handle user processors after internal processors
46-
for process in self.processors+self.options.processors:
47-
replay = process(replay)
45+
#Handle user processors after internal processors
46+
for process in self.processors+self.options.processors:
47+
replay = process(replay)
4848

49-
return replay
49+
return replay
5050

5151
def configure(self,**options):
5252
self.options.update(options)

sc2reader/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,4 @@ def __getitem__(self,key):
7777
except KeyError:
7878
return self.set3
7979

80-
READERS = ReaderMap()
80+
readers = ReaderMap()

sc2reader/readers.py

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,21 @@
88
#################################################
99

1010
class InitDataReader(object):
11-
def read(self, buffer, replay):
12-
13-
# Game clients
14-
for p in range(buffer.read_byte()):
11+
def __call__(self, buffer, replay):
12+
# A fixed length list of player names (includes observers)
13+
for player in range(buffer.read_byte()):
1514
name = buffer.read_string()
16-
if len(name) > 0:
15+
if name != "":
1716
replay.player_names.append(name)
18-
buffer.skip(5) #Always all zeros UNKNOWN
19-
20-
# UNKNOWN
21-
buffer.skip(5) # Unknown
22-
buffer.read_chars(4) # Always Dflt
23-
buffer.skip(15) #Unknown
17+
buffer.skip(5) #Always all zeros
18+
19+
buffer.skip(24) #Fixed Length data for unknown purpose
20+
2421
sc_account_id = buffer.read_string()
25-
22+
2623
buffer.skip(684) # Fixed Length data for unknown purpose
2724

25+
# An array of map information, could do much more with this
2826
while( buffer.read_chars(4).lower() == 's2ma' ):
2927
buffer.skip(2)
3028
replay.realm = buffer.read_string(2).lower()
@@ -33,11 +31,11 @@ def read(self, buffer, replay):
3331
#################################################
3432

3533
class AttributeEventsReader(object):
36-
def read(self, buffer, replay):
34+
def __call__(self, buffer, replay):
3735
self.load_header(replay, buffer)
3836

3937
replay.attributes = list()
40-
for i in range(0, buffer.read_int(LITTLE_ENDIAN)):
38+
for i in range(buffer.read_int(LITTLE_ENDIAN)):
4139
replay.attributes.append(Attribute([
4240
buffer.read_int(LITTLE_ENDIAN), #Header
4341
buffer.read_int(LITTLE_ENDIAN), #Attr Id
@@ -58,7 +56,7 @@ class DetailsReader(object):
5856
color_fields = ('a','r','g','b',)
5957
player_fields = ('name','bnet','race','color','?','?','handicap','?','result')
6058

61-
def read(self, buffer, replay):
59+
def __call__(self, buffer, replay):
6260
data = buffer.read_data_struct()
6361

6462
for pid, pdata in enumerate(data[0]):
@@ -99,42 +97,36 @@ def read(self, buffer, replay):
9997
##################################################
10098

10199
class MessageEventsReader(object):
102-
def read(self, buffer, replay):
100+
def __call__(self, buffer, replay):
103101
replay.messages, time = list(), 0
104102

105-
while(buffer.left != 0):
103+
while(buffer.left):
106104
time += buffer.read_timestamp()
107105
player_id = buffer.read_byte() & 0x0F
108106
flags = buffer.read_byte()
109-
107+
110108
if flags & 0xF0 == 0x80:
111109
# Pings, TODO: save and use data somewhere
112110
if flags & 0x0F == 3:
113111
x = buffer.read_int(LITTLE_ENDIAN)
114112
y = buffer.read_int(LITTLE_ENDIAN)
115-
# Some sort of header code
113+
114+
# Store recieved messages to later determine the recording
115+
# player by process of elimination during post-processing
116116
elif flags & 0x0F == 0:
117117
buffer.skip(4) # UNKNOWN
118-
# XXX why?
119118
replay.other_people.add(player_id)
120-
119+
121120
elif flags & 0x80 == 0:
122-
target = flags & 0x03
123-
length = buffer.read_byte()
124-
125-
# Flags for additional length in message
126-
if flags & 0x08:
127-
length += 64
128-
if flags & 0x10:
129-
length += 128
130-
121+
target,extension = flags & 0x03, (flags & 0x18) << 3
122+
length = buffer.read_byte() + extension
131123
text = buffer.read_chars(length)
132124
replay.messages.append(Message(time, player_id, target, text))
133125

134126
####################################################
135127

136128
class GameEventsBase(object):
137-
def read(self, buffer, replay):
129+
def __call__(self, buffer, replay):
138130
replay.events, frames = list(), 0
139131

140132
PARSERS = {
@@ -150,8 +142,7 @@ def read(self, buffer, replay):
150142
start = buffer.cursor
151143

152144
frames += buffer.read_timestamp()
153-
pid = buffer.shift(5)
154-
type, code = buffer.shift(3), buffer.read_byte()
145+
pid,type,code = buffer.shift(5), buffer.shift(3), buffer.read_byte()
155146
#print "Type %X - Code %X - Start %X" % (type,code,start)
156147

157148
parser = PARSERS.get(type,lambda x:None)(code)

0 commit comments

Comments
 (0)