Add support for HCA with subkey from .awb [Dragalia Lost (Mobile)]

This commit is contained in:
bnnm 2019-07-07 21:04:56 +02:00
parent 1a4dbc83d3
commit 5d1dd63182
3 changed files with 20 additions and 13 deletions

View File

@ -11,7 +11,7 @@ VGMSTREAM * init_vgmstream_awb(STREAMFILE *streamFile) {
size_t subfile_size;
int total_subsongs, target_subsong = streamFile->stream_index;
//uint32_t flags;
uint16_t alignment;//, derivation;
uint16_t alignment, subkey;
awb_type type;
char *extension = NULL;
@ -26,8 +26,8 @@ VGMSTREAM * init_vgmstream_awb(STREAMFILE *streamFile) {
//flags = read_32bitLE(0x08,streamFile);
total_subsongs = read_32bitLE(0x08,streamFile);
alignment = (uint16_t)read_16bitLE(0x0c,streamFile);
//derivation = (uint16_t)read_16bitLE(0x0e,streamFile);
alignment = (uint16_t)read_16bitLE(0x0c,streamFile);
subkey = (uint16_t)read_16bitLE(0x0e,streamFile);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail;
@ -86,7 +86,7 @@ VGMSTREAM * init_vgmstream_awb(STREAMFILE *streamFile) {
switch(type) {
case HCA: /* most common */
vgmstream = init_vgmstream_hca(temp_streamFile);
vgmstream = init_vgmstream_hca_subkey(temp_streamFile, subkey);
if (!vgmstream) goto fail;
break;
case ADX: /* Okami HD (PS4) */

View File

@ -2,13 +2,18 @@
#include "hca_keys.h"
#include "../coding/coding.h"
static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_keycode);
static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_keycode, uint16_t subkey);
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) {
return init_vgmstream_hca_subkey(streamFile, 0x0000);
}
VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey) {
VGMSTREAM * vgmstream = NULL;
hca_codec_data * hca_data = NULL;
unsigned long long keycode = 0;
/* checks */
if ( !check_extensions(streamFile, "hca"))
return NULL;
@ -34,7 +39,7 @@ VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) {
keycode = key * ( ((uint64_t)sub << 16u) | ((uint16_t)~sub + 2u) );
}
else {
find_hca_key(hca_data, &keycode);
find_hca_key(hca_data, &keycode, subkey);
}
clHCA_SetKey(hca_data->handle, keycode); //maybe should be done through hca_decoder.c?
@ -96,7 +101,7 @@ static inline void test_key(hca_codec_data * hca_data, uint64_t key, uint16_t su
}
/* Try to find the decryption key from a list. */
static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_keycode) {
static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_keycode, uint16_t subkey) {
const size_t keys_length = sizeof(hcakey_list) / sizeof(hcakey_info);
int best_score = -1;
int i,j;
@ -109,18 +114,19 @@ static void find_hca_key(hca_codec_data * hca_data, unsigned long long * out_key
size_t subkeys_size = hcakey_list[i].subkeys_size;
const uint16_t *subkeys = hcakey_list[i].subkeys;
if (subkeys_size > 0) {
/* try once with external subkey, if any */
test_key(hca_data, key, subkey, &best_score, out_keycode);
if (best_score == 1) /* best possible score */
goto done;
/* try subkey list */
if (subkeys_size > 0 && subkey == 0) {
for (j = 0; j < subkeys_size; j++) {
test_key(hca_data, key, subkeys[j], &best_score, out_keycode);
if (best_score == 1) /* best possible score */
goto done;
}
}
else {
test_key(hca_data, key, 0, &best_score, out_keycode);
if (best_score == 1) /* best possible score */
goto done;
}
}
done:

View File

@ -131,6 +131,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, ov_callb
#endif
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_hca_subkey(STREAMFILE *streamFile, uint16_t subkey);
#ifdef VGM_USE_FFMPEG
VGMSTREAM * init_vgmstream_ffmpeg(STREAMFILE *streamFile);