IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> Dogfight: Battle for the Pacific [.PAK]
PavelDAS
Oct 9 2025, 19:29
Сообщение #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);


--------------------
|__--__|
***|***
___|___
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
-=CHE@TER=-
Oct 10 2025, 08:07
Сообщение #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
Первые три файла, действительно, нули, как в имени, так и в смещении-размере.
Такие файловые записи нужно просто пропускать и игнорировать.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 15th October 2025 - 15:19