![]() |
Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
PavelDAS |
![]()
Сообщение
#1
|
Newbie ![]() Группа: Authorized Сообщений: 6 Регистрация: 21-September 25 Из: Minsk Пользователь №: 18,037 Спасибо сказали: 0 раз(а) ![]() |
*.pak (Dogfight: Battle for the Pacific)
Версия от Акеллы. Распаковал успешно, но есть проблема. Длина файлов иногда начитается на 00 и это ломает логику. Как правильно тут поступить? Или как понять сколько нулей между данными? Пример плохого файла 2_ScoreKill1.wav CODE <?php /* Распаковка pak *** Dogfight: Battle for the Pacific by PavelDAS :: 2025-09-14 Data.pak Block::Header (228 B) 03 : 50 41 4b - PAK 00 04 : 48 00 00 00 - ? (72) 02 (04) : 22 2e 00 00 - ? (11810) куча нулей (215 B) Block::Data начало cf 99 0c (850331) ** : имя файла 04 : смещение 04 : размер файла (куча нулей или без них) 360 b 2592 b 1512 b 217 b 216 b 0 b 288 b ... */ function cmp($a, $b) { return $a['offset'] <=> $b['offset']; } $arFileTable = []; // 1182 файла (версия Акелла) $cursorPos = 0; $headerSize = 228; // размер заголовка $dataOffset = 850331 - $headerSize; // начало блока с файлами // пропускаем заголовок $fileName = __DIR__ . '/' . 'Data.pak'; $f = fopen($fileName, 'r'); fseek($f, $headerSize); // формируем таблицу файлов while ($cursorPos < $dataOffset) { // читаем имя файла, пока не 00 $fileName = ''; do { $symbol = fread($f, 1); $fileName .= $symbol; $cursorPos++; } while (ord($symbol) != 0x00); // пропускаем символы до смещения while(ord(fread($f, 1)) == 0x00) { $cursorPos++; } fseek($f, -1, SEEK_CUR); //$cursorPos -= 1; // считаем смещение+размер if (trim($fileName) == '2_ScoreKill1.wav') // hack { fseek($f, -1, SEEK_CUR); } $offset = fread($f, 4); $size = fread($f, 4); $cursorPos += 8; // пропускаем символы до нового названия while(ord(fread($f, 1)) == 0x00){ $cursorPos++; } fseek($f, -1, SEEK_CUR); //$cursorPos -= 1; $arFileTable[] = [ 'name' => trim($fileName), 'offset' => unpack('V', $offset)[1], 'size' => unpack('V', $size)[1] ]; } usort($arFileTable, "cmp"); //сортируем file_put_contents('dat/!__array.txt', print_r($arFileTable, true)); // выдираем файлы foreach ($arFileTable as $file) { fseek($f, $file['offset']); if ($file['size'] > 0) // messages.log пустой file_put_contents('dat/' . $file['name'], fread($f, $file['size'])); else file_put_contents('dat/' . $file['name'], ''); } fclose($f); -------------------- |__--__|
***|*** ___|___ |
-=CHE@TER=- |
![]()
Сообщение
#2
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,388 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 322 раз(а) ![]() |
Про версию от Акеллы ничего сказать не могу, но в игре формат такой (must be означает, что если значение отлично от указанного, то игра считает файл повреждённым и не может загрузить):
CODE char[4] - magic, must be "PAK\0" Первые три файла, действительно, нули, как в имени, так и в смещении-размере.dword - [size] of file record, must be 72 dword - file records [count] for each of [count] file record (72 bytes): char[64] - file name (ASCIIZ) dword - file offs dword - file size Такие файловые записи нужно просто пропускать и игнорировать. |
![]() ![]() |
Упрощённая версия | Сейчас: 15th October 2025 - 15:19 |