Skip to content

Commit 13f1296

Browse files
(archives.runecraft) figured out Entry.offset
1 parent a8b6303 commit 13f1296

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

bsp_tool/archives/runecraft.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# -- partial winrar support?
55
from __future__ import annotations
66
import io
7-
from typing import List
7+
from typing import Dict, List
88

99
from .. import core
1010
from ..utils import binary
@@ -17,20 +17,18 @@
1717

1818
# TODO: calculate values matching .pvr offsets
1919
class Entry(core.Struct):
20-
# sum of unknown[2] is less than filesize
21-
# -- 79 bytes short of the total filesize
22-
# -- the last 79 bytes of FILES.PAK are NULL
23-
# look like lengths, but idk
24-
__slots__ = ["unknown"]
20+
unknown: int # name hash? unique for every entry
21+
offset: int # -8
22+
length: int
23+
__slots__ = ["unknown", "offset", "length"]
2524
_format = "3I"
26-
_arrays = {"unknown": 3}
2725

2826

2927
class Pak(base.Archive):
3028
ext = "*.pak"
3129
_file: io.BytesIO
32-
entries: List[Entry]
33-
# entries: Dict[str, Entry]
30+
entries: Dict[str, Entry]
31+
# NOTE: names are currently placeholders
3432

3533
def __init__(self):
3634
super().__init__()
@@ -40,8 +38,18 @@ def __repr__(self) -> str:
4038
descriptor = f"{len(self.entries)} files"
4139
return f"<{self.__class__.__name__} {descriptor} @ 0x{id(self):016X}>"
4240

43-
# TODO: def read(self, filepath: str) -> bytes:
44-
# TODO: def namelist(self) -> List[str]:
41+
def read(self, filepath: str) -> bytes:
42+
assert filepath in self.entries
43+
entry = self.entries[filepath]
44+
self._file.seek(entry.offset + 8)
45+
return self._file.read(entry.length)
46+
47+
def namelist(self) -> List[str]:
48+
return [
49+
f"{entry.unknown:08X}"
50+
for entry in sorted(
51+
self.entries.values(),
52+
key=lambda e: (e.offset, e.length))]
4553

4654
@classmethod
4755
def from_stream(cls, stream: io.BytesIO) -> Pak:
@@ -50,14 +58,13 @@ def from_stream(cls, stream: io.BytesIO) -> Pak:
5058
assert stream.read(4) == b"NPCK", "not a .pak file"
5159
# guessing
5260
num_entries = binary.read_struct(stream, "I")
53-
out.entries = [
54-
Entry.from_stream(stream)
55-
for i in range(num_entries)]
56-
# vaild file data starts right after this
57-
# unsure of length tho
58-
# 6942 bytes of configs (likely multiple files)
59-
# a few bytes of data (likely ints)
60-
# sega copyright message (small text file?)
61-
# not seeing any sort of filename table
62-
# however plaintext files reference filenames
61+
out.entries = {
62+
f"{entry.unknown:08X}": entry
63+
for entry in [
64+
Entry.from_stream(stream)
65+
for i in range(num_entries)]}
66+
# NOTE: entries are listed in ascending `unknown` order
67+
# -- not in offset order
68+
# NOTE: some entries are 0 bytes in length
69+
# NOTE: 80 blank bytes at end of file unaccounted for?
6370
return out

0 commit comments

Comments
 (0)