@@ -21,71 +21,205 @@ def __call__(self, data, replay):
21
21
22
22
class InitDataReader_Base (Reader ):
23
23
24
- def get_player_names (self , data , replay ):
25
- # The first block of the replay.initData file represents a list of
26
- # human player names; computers are no recorded. This list appears to
27
- # always be 16 long, with "" names filling in the balance. Each name
28
- # is followed by a 5 byte string that appears to be always all zeros.
29
- player_names = list ()
30
- for player in range (data .read_uint8 ()):
31
- name = data .read_aligned_bytes (data .read_uint8 ())
32
- data .read_bytes (5 )
33
- if name :
34
- player_names .append (name )
35
- return player_names
36
-
37
24
def __call__ (self , data , replay ):
38
25
data = BitPackedDecoder (data )
39
26
40
- player_names = self .get_player_names (data , replay )
41
-
42
- # The next block contains information about the structure of the MPQ
43
- # archive. We don't read this information because we've got mpyq for
44
- # that. Its split into 3 sections because of the variable length segment
45
- # in the middle that prevents bulk skipping. The last section also
46
- # appears to be variable length, hack it to do a find for the section
47
- # we are looking for.
48
- data .read_bytes (24 )
49
- #sc_account_id = data.read_string()
50
- distance = data .read_range (data .tell (), data .length ).find ('s2ma' )
51
- data .read_bytes (distance )
52
-
53
- # The final block of this file that we concern ourselves with is a list
54
- # of what appears to be map data with the s2ma header on each element.
55
- # Each element consists of two unknown bytes, a realm id (e.g EU or US)
56
- # and a map hash which probably ties back to the sc2map files.
57
- #
58
- # Some replays don't seem to have a maps section at all, now we can't
59
- # know what gateway its from? Very strange...
60
- #
61
- # TODO: Figure out how we could be missing a maps section.
62
- map_data = list ()
63
- while data .peek (4 ) == 's2ma' :
64
- map_data .append (DepotFile (data .read_bytes (40 )))
27
+ init_data = dict ( #58
28
+ player_init_data = [dict ( #38
29
+ name = data .read_aligned_bytes (data .read_uint8 ()),
30
+ random_seed = data .read_uint32 (),
31
+ race_preference = data .read_uint8 () if data .read_bool () else None , #38
32
+ team_preference = data .read_uint8 () if data .read_bool () else None , #39
33
+ test_map = data .read_bool (),
34
+ test_auto = data .read_bool (),
35
+ examine = data .read_bool (),
36
+ observe = data .read_bits (2 ),
37
+ ) for i in range (data .read_bits (5 ))
38
+ ],
39
+
40
+ game_description = dict ( # 48
41
+ random_value = data .read_uint32 (), # 4
42
+ game_cache_name = data .read_aligned_bytes (data .read_bits (10 )), # 24
43
+ game_options = dict ( #40
44
+ lock_teams = data .read_bool (), #27
45
+ teams_together = data .read_bool (),
46
+ advanced_shared_control = data .read_bool (),
47
+ random_races = data .read_bool (),
48
+ battle_net = data .read_bool (),
49
+ amm = data .read_bool (),
50
+ competitive = data .read_bool (),
51
+ no_victory_or_defeat = data .read_bool (),
52
+ fog = data .read_bits (2 ), #19
53
+ observers = data .read_bits (2 ), #19
54
+ user_difficulty = data .read_bits (2 ), #19
55
+ client_debug_flags = data .read_uint64 (), #15
56
+ ),
57
+ game_speed = data .read_bits (3 ),
58
+ game_type = data .read_bits (3 ),
59
+ max_users = data .read_bits (5 ),
60
+ max_observers = data .read_bits (5 ),
61
+ max_players = data .read_bits (5 ),
62
+ max_teams = data .read_bits (4 )+ 1 ,
63
+ max_colors = data .read_bits (6 ),
64
+ max_races = data .read_uint8 ()+ 1 ,
65
+ max_controls = data .read_uint8 ()+ 1 ,
66
+ map_size_x = data .read_uint8 (),
67
+ map_size_y = data .read_uint8 (),
68
+ map_file_sync_checksum = data .read_uint32 (),
69
+ map_file_name = data .read_aligned_bytes (data .read_bits (11 )),
70
+ map_author_name = data .read_aligned_bytes (data .read_uint8 ()),
71
+ mod_file_sync_checksum = data .read_uint32 (),
72
+ slot_descriptions = [dict ( #47
73
+ allowed_colors = data .read_bits (data .read_bits (6 )),
74
+ allowed_races = data .read_bits (data .read_uint8 ()),
75
+ allowedDifficulty = data .read_bits (data .read_bits (6 )),
76
+ allowedControls = data .read_bits (data .read_uint8 ()),
77
+ allowed_observe_types = data .read_bits (data .read_bits (2 )),
78
+ ) for i in range (data .read_bits (5 ))],
79
+ default_difficulty = data .read_bits (6 ),
80
+ cache_handles = [
81
+ DepotFile (data .read_aligned_bytes (40 )) for i in range (data .read_bits (6 ))
82
+ ],
83
+ is_blizzardMap = data .read_bool (),
84
+ is_premade_ffa = data .read_bool (),
85
+ ),
86
+ )
87
+ """ # For builds <= 1.5.4 this won't work.
88
+ lobby_state = dict( #56
89
+ phase = data.read_bits(3),
90
+ max_users = data.read_bits(5),
91
+ max_observers = data.read_bits(5),
92
+ slots = [dict( #54
93
+ control = data.read_uint8(),
94
+ user_id = data.read_bits(4) if data.read_bool() else None,
95
+ team_id = data.read_bits(4),
96
+ colorPref = data.read_bits(5) if data.read_bool() else None,
97
+ race_pref = data.read_uint8() if data.read_bool() else None,
98
+ difficulty = data.read_bits(6),
99
+ handicap = data.read_bits(7),
100
+ observe = data.read_bits(2),
101
+ rewards = [data.read_uint32() for i in range(data.read_bits(6))],
102
+ toon_handle = data.read_aligned_bytes(data.read_bits(7)), # 14
103
+ licenses = [data.read_uint32() for i in range(data.read_bits(9))], # 56
104
+ ) for i in range(data.read_bits(5))], # 58
105
+ random_seed = data.read_uint32(),
106
+ host_user_id = data.read_bits(4) if data.read_bool() else None, # 52
107
+ is_single_player = data.read_bool(), # 27
108
+ game_duration = data.read_uint32(), # 4
109
+ default_difficulty = data.read_bits(6), # 1
110
+ ),
111
+ )"""
65
112
66
- # Return the extracted information inside an AttributeDict.
67
113
return AttributeDict (
68
- map_data = map_data ,
69
- player_names = player_names ,
114
+ map_data = init_data [ 'game_description' ][ 'cache_handles' ] ,
115
+ player_names = [ d [ 'name' ] for d in init_data [ 'player_init_data' ] if d [ 'name' ]] ,
70
116
sc_account_id = None ,#sc_account_id,
71
117
)
72
118
73
119
class InitDataReader_24764 (InitDataReader_Base ):
74
- def get_player_names (self , data , replay ):
75
- player_names = list ()
76
- for player in range (data .read_uint8 ()):
77
- name = data .read_aligned_bytes (data .read_uint8 ())
78
-
79
- # Flag is 1 for multiplayer, 0 for single player
80
- if data .read_bits (1 ):
81
- clan_name = data .read_aligned_bytes (data .read_uint8 ())
82
- unknown = data .read_bits (42 )
83
120
84
- data .read_bytes (5 )
85
- if name :
86
- player_names .append (name )
87
- return player_names
121
+ def __call__ (self , data , replay ):
122
+ data = BitPackedDecoder (data )
88
123
124
+ init_data = dict (
125
+ player_init_data = [dict (
126
+ name = data .read_aligned_bytes (data .read_uint8 ()),
127
+ clan_tag = data .read_aligned_bytes (data .read_uint8 ()) if data .read_bool () else "" , # 36
128
+ highest_league = data .read_uint8 () if data .read_bool () else None , #20
129
+ combined_race_levels = data .read_uint32 () if data .read_bool () else None , #37
130
+ random_seed = data .read_uint32 (),
131
+ race_preference = data .read_uint8 () if data .read_bool () else None , #38
132
+ team_preference = data .read_uint8 () if data .read_bool () else None , #39
133
+ test_map = data .read_bool (),
134
+ test_auto = data .read_bool (),
135
+ examine = data .read_bool (),
136
+ custom_interface = data .read_bool (),
137
+ observe = data .read_bits (2 ),
138
+ ) for i in range (data .read_bits (5 ))
139
+ ],
140
+
141
+ game_description = dict (
142
+ random_value = data .read_uint32 (), # 4
143
+ game_cache_name = data .read_aligned_bytes (data .read_bits (10 )), # 24
144
+ game_options = dict (
145
+ lock_teams = data .read_bool (), #27
146
+ teams_together = data .read_bool (),
147
+ advanced_shared_control = data .read_bool (),
148
+ random_races = data .read_bool (),
149
+ battle_net = data .read_bool (),
150
+ amm = data .read_bool (),
151
+ competitive = data .read_bool (),
152
+ no_victory_or_defeat = data .read_bool (),
153
+ fog = data .read_bits (2 ), #19
154
+ observers = data .read_bits (2 ), #19
155
+ user_difficulty = data .read_bits (2 ), #19
156
+ client_debug_flags = data .read_uint64 (), #15
157
+ ),
158
+ game_speed = data .read_bits (3 ),
159
+ game_type = data .read_bits (3 ),
160
+ max_users = data .read_bits (5 ),
161
+ max_observers = data .read_bits (5 ),
162
+ max_players = data .read_bits (5 ),
163
+ max_teams = data .read_bits (4 )+ 1 ,
164
+ max_colors = data .read_bits (6 ),
165
+ max_races = data .read_uint8 ()+ 1 ,
166
+ max_controls = data .read_uint8 ()+ 1 ,
167
+ map_size_x = data .read_uint8 (),
168
+ map_size_y = data .read_uint8 (),
169
+ map_file_sync_checksum = data .read_uint32 (),
170
+ map_file_name = data .read_aligned_bytes (data .read_bits (11 )),
171
+ map_author_name = data .read_aligned_bytes (data .read_uint8 ()),
172
+ mod_file_sync_checksum = data .read_uint32 (),
173
+ slot_descriptions = [dict ( #50
174
+ allowed_colors = data .read_bits (data .read_bits (6 )),
175
+ allowed_races = data .read_bits (data .read_uint8 ()),
176
+ allowedDifficulty = data .read_bits (data .read_bits (6 )),
177
+ allowedControls = data .read_bits (data .read_uint8 ()),
178
+ allowed_observe_types = data .read_bits (data .read_bits (2 )),
179
+ allowed_ai_builds = data .read_bits (data .read_bits (7 )),
180
+ ) for i in range (data .read_bits (5 ))],
181
+ default_difficulty = data .read_bits (6 ),
182
+ default_AI_build = data .read_bits (7 ),
183
+ cache_handles = [
184
+ DepotFile (data .read_aligned_bytes (40 )) for i in range (data .read_bits (6 ))
185
+ ],
186
+ is_blizzardMap = data .read_bool (),
187
+ is_premade_ffa = data .read_bool (),
188
+ is_coop_mode = data .read_bool (),
189
+ ),
190
+
191
+ lobby_state = dict (
192
+ phase = data .read_bits (3 ),
193
+ max_users = data .read_bits (5 ),
194
+ max_observers = data .read_bits (5 ),
195
+ slots = [dict (
196
+ control = data .read_uint8 (),
197
+ user_id = data .read_bits (4 ) if data .read_bool () else None ,
198
+ team_id = data .read_bits (4 ),
199
+ colorPref = data .read_bits (5 ) if data .read_bool () else None ,
200
+ race_pref = data .read_uint8 () if data .read_bool () else None ,
201
+ difficulty = data .read_bits (6 ),
202
+ ai_build = data .read_bits (7 ),
203
+ handicap = data .read_bits (7 ),
204
+ observe = data .read_bits (2 ),
205
+ working_set_slot_id = data .read_uint8 () if data .read_bool () else None ,
206
+ rewards = [data .read_uint32 () for i in range (data .read_bits (6 ))],
207
+ toon_handle = data .read_aligned_bytes (data .read_bits (7 )), # 14
208
+ licenses = [data .read_uint32 () for i in range (data .read_bits (9 ))], # 56
209
+ ) for i in range (data .read_bits (5 ))], # 58
210
+ random_seed = data .read_uint32 (),
211
+ host_user_id = data .read_bits (4 ) if data .read_bool () else None , # 52
212
+ is_single_player = data .read_bool (), # 27
213
+ game_duration = data .read_uint32 (), # 4
214
+ default_difficulty = data .read_bits (6 ), # 1
215
+ default_ai_build = data .read_bits (7 ), # 0
216
+ ),
217
+ )
218
+ return AttributeDict (
219
+ map_data = init_data ['game_description' ]['cache_handles' ],
220
+ player_names = [d ['name' ] for d in init_data ['player_init_data' ] if d ['name' ]],
221
+ sc_account_id = None ,#sc_account_id,
222
+ )
89
223
90
224
91
225
class AttributesEventsReader_Base (Reader ):
0 commit comments