import
os
import
struct
class
Binary:
def
__init__(
self
, data: [bytearray, bytes,
str
]):
self
.index
=
0
if
isinstance
(data, bytearray):
self
.data
=
data
elif
isinstance
(data, bytes):
self
.data
=
bytearray(data)
elif
isinstance
(data,
str
):
self
.data
=
bytearray(data.encode(encoding
=
'utf-8'
))
else
:
raise
TypeError(
'data type is invalid:'
, data.__class__.__name__)
self
.size
=
len
(
self
.data)
def
read_int8(
self
)
-
>
int
:
ret
=
self
.data[
self
.index]
self
.index
+
=
1
return
ret
def
read_int16(
self
)
-
>
int
:
ret,
=
struct.unpack(
'h'
,
self
.data[
self
.index:
self
.index
+
2
])
self
.index
+
=
2
return
ret
def
read_int32(
self
)
-
>
int
:
ret,
=
struct.unpack(
'i'
,
self
.data[
self
.index:
self
.index
+
4
])
self
.index
+
=
4
return
ret
def
read_int64(
self
)
-
>
int
:
ret,
=
struct.unpack(
'q'
,
self
.data[
self
.index:
self
.index
+
8
])
self
.index
+
=
8
return
ret
def
read_string(
self
)
-
>
str
:
pass
def
read_bytes(
self
, size:
int
)
-
> bytearray:
if
size >
self
.rest():
ret
=
self
.data[
self
.index:]
self
.index
+
=
self
.rest()
return
ret
ret
=
self
.data[
self
.index:
self
.index
+
size]
self
.index
+
=
size
return
ret
def
__len__(
self
):
return
len
(
self
.data)
def
rest(
self
)
-
>
int
:
return
len
(
self
.data)
-
self
.index
@staticmethod
def
bytes2str(data: [bytearray, bytes]):
out
=
''
if
data
is
None
or
len
(data)
=
=
0
:
return
'Null'
for
b
in
data:
if
out:
out
+
=
','
out
+
=
'0x%02X'
%
b
out
+
=
'\n'
out
+
=
data.decode(
'utf-8'
)
return
out
class
PakData:
def
__init__(
self
, br: Binary):
self
.version
=
br.read_int32()
self
.count
=
br.read_int32()
self
.coding
=
br.read_int8()
self
.resources
=
list
()
for
i
in
range
(
self
.count):
item
=
{
'id'
: br.read_int16(),
'offset'
: br.read_int32(),
'data'
: bytearray(),
'size'
:
0
}
self
.resources.append(item)
for
i, item
in
enumerate
(
self
.resources):
if
i
+
1
<
self
.count:
item[
'size'
]
=
self
.resources[i
+
1
][
'offset'
]
-
item[
'offset'
]
else
:
item[
'size'
]
=
len
(br)
-
item[
'offset'
]
item[
'data'
]
=
br.data[item[
'offset'
]:item[
'offset'
]
+
item[
'size'
]]
class
PakFile:
def
__init__(
self
, path:
str
):
self
.path
=
path
if
os.path.exists(path):
self
.decode()
return
self
.data
=
None
def
set_path(
self
, path):
self
.path
=
path
def
decode(
self
)
-
>
int
:
if
os.path.exists(
self
.path)
is
False
:
return
-
1
with
open
(
self
.path, mode
=
'rb'
) as
file
:
raw
=
bytearray(
file
.read())
file
.close()
br
=
Binary(raw)
self
.data
=
PakData(br)
def
main():
pak
=
PakFile(r
'.\zh-CN.pak'
)
if
isinstance
(pak.data, PakData):
print
(
'版本:'
, pak.data.version)
print
(
'数量:'
, pak.data.count)
print
(
'编码:'
, pak.data.coding)
for
i
in
range
(pak.data.count):
print
(
'ID:'
, pak.data.resources[i][
'id'
])
print
(
'偏移:'
, pak.data.resources[i][
'offset'
])
print
(
'大小:'
, pak.data.resources[i][
'size'
])
print
(
'内容:'
, Binary.bytes2str(pak.data.resources[i][
'data'
]))
if
__name__
=
=
'__main__'
:
main()