22from datetime import datetime
33from collections import defaultdict
44
5- from objects import Attribute , Message , Player , Event
5+ from objects import Attribute , Message , Player , Observer , Event
66from eventparsers import *
77from utils import ByteStream
88from exceptions import ParseError
@@ -41,12 +41,17 @@ def get_initdata_parser(build):
4141 return InitdataParser ()
4242
4343class InitdataParser (object ):
44- def load (self ,replay ,filecontents ):
44+ def load (self , replay , filecontents ):
4545 bytes = ByteStream (filecontents )
4646 num_players = bytes .get_big_8 ()
47- for p in range (0 ,num_players ):
47+ for p in range (0 , num_players ):
4848 name_length = bytes .get_big_8 ()
4949 name = bytes .get_string (name_length )
50+
51+ # Add every player as observer for now
52+ if name_length > 0 :
53+ replay .observers .append (Observer (p + 1 , name ))
54+
5055 bytes .skip (5 )
5156
5257 bytes .skip (5 ) # Unknown
@@ -107,10 +112,10 @@ def load(self, replay, filecontents):
107112
108113 replay .type = data [16 ]['Game Type' ]
109114
110- #Set player attributes as available, requires already populated player list
115+ #Set player attributes as available, requires already populated player list
111116 for pid , attributes in data .iteritems ():
112117 if pid == 16 : continue
113- player = replay .player [pid ]
118+ player = replay .actor [pid ]
114119 player .color_text = attributes ['Color' ]
115120 player .team = attributes ['Teams' + replay .type ]
116121 player .choosen_race = attributes ['Race' ]
@@ -131,10 +136,17 @@ def load_header(self, replay, bytes):
131136class DetailParser (object ):
132137 def load (self , replay , filecontents ):
133138 data = ByteStream (filecontents ).parse_serialized_data ()
134-
139+
140+ pids = []
135141 for pid , pdata in enumerate (data [0 ]):
136- replay .add_player (Player (pid + 1 , pdata , replay .realm )) #shift the id to start @ 1
137-
142+ pids .append (pid + 1 )
143+ replay .add_actor (Player (pid + 1 , pdata , replay .realm )) #shift the id to start @ 1
144+
145+ # Remove actual players from the observers we saved during parsing of initdata.
146+ replay .observers = [obs for obs in replay .observers if not obs .pid in pids ]
147+ for observer in replay .observers :
148+ replay .add_actor (observer )
149+
138150 replay .map = data [1 ].decode ("hex" )
139151 replay .file_time = data [5 ]
140152
@@ -170,10 +182,7 @@ def load(self, replay, filecontents):
170182 #some sort of header code
171183 elif flags & 0x0F == 0 :
172184 bytes .skip (4 )
173- if player_id <= len (replay .players ):
174- replay .player [player_id ].recorder = False
175- else :
176- pass #This "player" is an observer or something
185+ replay .actor [player_id ].recorder = False
177186
178187 elif flags & 0x80 == 0 :
179188 target = flags & 0x03
@@ -187,20 +196,20 @@ def load(self, replay, filecontents):
187196
188197 text = bytes .get_string (length )
189198 try :
190- replay .messages .append (Message (time , replay .player [player_id ], target , text ))
199+ replay .messages .append (Message (time , replay .actor [player_id ], target , text ))
191200 except KeyError :
192201 # This was added because some replay sites added their own tampered
193202 # messages to replays with non-existent player_id.
194203 #
195204 # This will simply ignore and fail silently if such message is
196205 # found.
197206 pass
198-
199- recorders = [player for player in replay .players if player and player .recorder == True ]
207+
208+ recorders = [actor for actor in replay .actors if actor and actor .recorder == True ]
200209 if len (recorders ) > 1 :
201210 raise ValueError ("There should be 1 and only 1 recorder; %s were found" % len (recorders ))
202211 elif len (recorders ) == 0 :
203- #If there are no recorders, then the recorder must not be a player, spectator or referee then
212+ #If there are no recorders, then the recorder must not be a player, spectator or referee then
204213 replay .recorder = None
205214 else :
206215 replay .recorder = recorders [0 ]
0 commit comments