|
8 | 8 |
|
9 | 9 | from mgz.util import get_version, unpack, Version, as_hex |
10 | 10 |
|
| 11 | +PLAYER_END = b'\xff\xff\xff\xff\xff\xff\xff\xff.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b' |
11 | 12 | ZLIB_WBITS = -15 |
12 | 13 | CLASSES = [b'\x0a', b'\x1e', b'\x46', b'\x50', b'\x14'] |
13 | 14 | BLOCK_END = b'\x00\x0b' |
@@ -139,13 +140,19 @@ def parse_player(header, player_number, num_players, save): |
139 | 140 | data = header.read(100) |
140 | 141 | device = data[8] |
141 | 142 | # Jump to the end of player data |
142 | | - player_end = re.search(b'\xff\xff\xff\xff\xff\xff\xff\xff.\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b', data, re.DOTALL) |
| 143 | + player_end = re.search(PLAYER_END, data, re.DOTALL) |
143 | 144 | if not player_end: |
144 | | - # only a failure if this is not the last player, since we seek to the next block anyway |
145 | | - # this issue happens on restored games |
146 | | - if player_number < num_players - 1: |
| 145 | + # Normally this is 26 bytes in, |
| 146 | + # But in some cases (probably where object parsing failed), |
| 147 | + # it can be tens of thousands of bytes. So we have to `read()` everything |
| 148 | + offset = header.tell() |
| 149 | + data = header.read() |
| 150 | + player_end = re.search(PLAYER_END, data, re.DOTALL) |
| 151 | + if not player_end and player_number < num_players - 1: |
| 152 | + # this issue happens on restored games |
| 153 | + # only a failure if this is not the last player, since we seek to the next block anyway |
147 | 154 | raise RuntimeError("could not find player end") |
148 | | - else: |
| 155 | + if player_end: |
149 | 156 | header.seek(offset + player_end.end()) |
150 | 157 |
|
151 | 158 | return dict( |
|
0 commit comments