forked from Fruithapje21/TOTK-Ultrawide
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfile_archive.py
120 lines (91 loc) · 3.74 KB
/
file_archive.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import os
import SarcLib
import zstandard as zstd
def decompress_zs(zs_path, blarc_path, zsdic_path):
with open(zsdic_path, 'rb') as f:
dict_data = zstd.ZstdCompressionDict(f.read())
dctx = zstd.ZstdDecompressor(dict_data=dict_data)
with open(zs_path, 'rb') as ifh, open(blarc_path, 'wb') as ofh:
decompressed_data = dctx.decompress(ifh.read())
ofh.write(decompressed_data)
def compress_zs(blarc_path, zs_path, zsdic_path):
with open(zsdic_path, 'rb') as f:
dict_data = zstd.ZstdCompressionDict(f.read())
cctx = zstd.ZstdCompressor(dict_data=dict_data, level=14)
with open(blarc_path, 'rb') as ifh, open(zs_path, 'wb') as ofh:
compressed_data = cctx.compress(ifh.read())
ofh.write(compressed_data)
def extract_blarc(blarc_path, out_dir):
with open(blarc_path, "rb") as f:
inb = f.read()
arc = SarcLib.SARC_Archive()
arc.load(inb)
root = out_dir
if not os.path.isdir(root):
os.mkdir(root)
files = []
def getAbsPath(folder, path):
nonlocal root
nonlocal files
for checkObj in folder.contents:
if isinstance(checkObj, SarcLib.File):
files.append(["/".join([path, checkObj.name]), checkObj.data])
else:
path_ = os.path.join(root, "/".join([path, checkObj.name]))
if not os.path.isdir(path_):
os.mkdir(path_)
getAbsPath(checkObj, "/".join([path, checkObj.name]))
for checkObj in arc.contents:
if isinstance(checkObj, SarcLib.File):
files.append([checkObj.name, checkObj.data])
else:
path = os.path.join(root, checkObj.name)
if not os.path.isdir(path):
os.mkdir(path)
getAbsPath(checkObj, checkObj.name)
for file, fileData in files:
with open(os.path.join(root, file), "wb") as out:
out.write(fileData)
def repack_blarc(root, out_file):
"""
Pack the files and folders in the root folder.
"""
if "\\" in root:
root = "/".join(root.split("\\"))
if root[-1] == "/":
root = root[:-1]
arc = SarcLib.SARC_Archive(endianness='>')
lenroot = len(root.split("/"))
for path, dirs, files in os.walk(root):
if "\\" in path:
path = "/".join(path.split("\\"))
lenpath = len(path.split("/"))
if lenpath == lenroot:
path = ""
else:
path = "/".join(path.split("/")[lenroot - lenpath:])
for file in files:
if path:
filename = ''.join([path, "/", file])
else:
filename = file
fullname = ''.join([root, "/", filename])
i = 0
for folder in filename.split("/")[:-1]:
if not i:
exec("folder%i = SarcLib.Folder(folder + '/'); arc.addFolder(folder%i)".replace('%i', str(i)))
else:
exec("folder%i = SarcLib.Folder(folder + '/'); folder%m.addFolder(folder%i)".replace('%i', str(i)).replace('%m', str(i - 1)))
i += 1
with open(fullname, "rb") as f:
inb = f.read()
hasFilename = True
if file[:5] == "hash_":
hasFilename = False
if not i:
arc.addFile(SarcLib.File(file, inb, hasFilename))
else:
exec("folder%m.addFile(SarcLib.File(file, inb, hasFilename))".replace('%m', str(i - 1)))
data, maxAlignment = arc.save()
with open(out_file, "wb+") as output:
output.write(data)