Skip to content

Workaround for #10033 (casc_extract: "Invalid file length") #10399

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: thewarwithin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion casc_extract/build_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def open(self):
# Slight hack to get the configuration file read easily
conf_str = '[base]\n' + open(build_cfg_path, 'r').read()
conf_str_fp = io.StringIO(conf_str)
self.cfg.readfp(conf_str_fp)
self.cfg.read_file(conf_str_fp)

print(f'Wow build: {build_version}')

Expand Down
11 changes: 8 additions & 3 deletions casc_extract/casc.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ def extract_blte_file(self, file_name):
def extract_data(self, file_key, file_md5sum, data_file_number,
data_file_offset, blte_file_size):
path = os.path.join(self.options.data_dir, 'Data', 'data', f'data.{data_file_number:03d}')
file_key_hex = codecs.encode(file_key, 'hex').decode()

if not self.open(path):
return None
Expand All @@ -442,16 +443,20 @@ def extract_data(self, file_key, file_md5sum, data_file_number,
blte_len = struct.unpack('<I', self.fd.read(4))[0]

if blte_len != blte_file_size:
self.options.parser.error(
f'Invalid file length, expected {blte_file_size} got {blte_len}'
# FIXME: some files don't extract?
# https://github.com/simulationcraft/simc/issues/10033
print(
f'Invalid file length, expected {blte_file_size} got '
f'{blte_len} (for {file_key_hex})'
)
return None

# Key is apparently in reverse byte order, and only 9 bytes of it are relevant (as in the
# index structures)
for idx in range(0, 9):
if file_key[idx] != key[len(key) - 1 - idx]:
self.options.parser.error(
f"Invalid file key for {codecs.encode(file_key, 'hex').decode('utf-8')}, "
f"Invalid file key for {file_key_hex}, "
f"got {codecs.encode(key, 'hex').decode('utf-8')}")

# Skip 10 bytes of unknown data
Expand Down
29 changes: 23 additions & 6 deletions casc_extract/casc_extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@
parser.add_option( '--ribbit', action = 'store_true', dest = 'ribbit', default = False, help = 'Use Ribbit for configuration information')
parser.add_option( '--bgdl', action = 'store_true', dest = 'bgdl', default = False, help = 'Download background downloader files' )
parser.add_option( '--custom', type='string', dest = 'custom_build', default = None, help = 'Use a custom Build Config')
parser.add_option(
'--continue_on_failure',
action='store_true',
default=False,
help='If any file fails to extract in "batch" or "unpack" mode, continue trying to extract other files',
)

if __name__ == '__main__':
(opts, args) = parser.parse_args()
Expand Down Expand Up @@ -108,7 +114,11 @@
print('Extracting %s (id=%d) ...' % (file_name, file_data_id))

if not blte.extract_file(*extract_data):
sys.exit(1)
print(f'Failed to extract data for {file_name}', file=sys.stderr)
if opts.continue_on_failure:
continue
else:
sys.exit(1)
else:
cdn = casc.CDNIndex(opts)
if not cdn.open():
Expand Down Expand Up @@ -151,14 +161,21 @@
result = blte.extract_buffer_to_file(data, os.path.join(output_path, file_name.replace('\\', '/')))
if not result:
print('Failed to extract data for %s %s' % (opts.locale, file_name), file=sys.stderr)
sys.exit(1)
if opts.continue_on_failure:
continue
else:
sys.exit(1)

elif opts.mode == 'unpack':
blte = casc.BLTEExtract(opts)
for file in args:
print('Extracting %s ...')
if not blte.extract_blte_file(file):
sys.exit(1)
for file_name in args:
print(f'Extracting {file_name}...')
if not blte.extract_blte_file(file_name):
print(f'Failed to extract data for {file_name}', file=sys.stderr)
if opts.continue_on_failure:
continue
else:
sys.exit(1)

elif opts.mode == 'extract':
build = None
Expand Down
Loading