mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
Create script to convert files between .arc and .zip
This commit is contained in:
parent
946464e314
commit
b4b12fa922
81
arcconv.py
Normal file
81
arcconv.py
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import sys, struct
|
||||
from zipfile import ZipFile, Path
|
||||
from io import BytesIO
|
||||
|
||||
|
||||
def usage(exe_name: str):
|
||||
print(f"usage: {exe_name} <command> <infile> <outfile>")
|
||||
print(" command: either arc2zip or zip2arc")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
exe_name = sys.argv[0]
|
||||
if len(sys.argv) != 4: usage(exe_name)
|
||||
command = sys.argv[1]
|
||||
in_filename = sys.argv[2]
|
||||
out_filename = sys.argv[3]
|
||||
|
||||
if command == "arc2zip":
|
||||
arc_to_zip(in_filename, out_filename)
|
||||
elif command == "zip2arc":
|
||||
zip_to_arc(in_filename, out_filename)
|
||||
else:
|
||||
usage(exe_name)
|
||||
|
||||
|
||||
def arc_to_zip(in_filename: str, out_filename: str):
|
||||
with open(in_filename, "rb") as file:
|
||||
data = file.read()
|
||||
buf = BytesIO(data)
|
||||
|
||||
with ZipFile(out_filename, "w") as zipfile:
|
||||
entry_count = struct.unpack(">I", buf.read(4))[0]
|
||||
files = []
|
||||
|
||||
for _ in range(entry_count):
|
||||
strlen = struct.unpack(">H", buf.read(2))[0]
|
||||
fmt = f">{strlen}s2I"
|
||||
fmt_size = struct.calcsize(fmt)
|
||||
(filename, offset, size) = struct.unpack(fmt, buf.read(fmt_size))
|
||||
filename = filename.decode("UTF-8").strip("\0").replace("\\", "/")
|
||||
file_path = Path(zipfile, filename)
|
||||
files.append((filename, data[offset:offset + size]))
|
||||
|
||||
# files.sort(key=lambda pair: pair[0])
|
||||
for filename, contents in files:
|
||||
zipfile.writestr(filename, contents)
|
||||
|
||||
|
||||
def zip_to_arc(in_filename: str, out_filename: str):
|
||||
data_buf = bytearray()
|
||||
|
||||
with open(out_filename, "wb") as out_file:
|
||||
files = []
|
||||
|
||||
with ZipFile(in_filename, "r") as zip_file:
|
||||
files.extend((file.filename, zip_file.read(file)) for file in zip_file.filelist)
|
||||
|
||||
# files.sort(key=lambda pair: pair[0])
|
||||
|
||||
header_length = (
|
||||
sum(len(file[0].encode('utf-8')) for file in files)
|
||||
+ len(files) * struct.calcsize(f">H2I")
|
||||
+ struct.calcsize("I")
|
||||
)
|
||||
|
||||
out_file.write(struct.pack(">I", len(files)))
|
||||
|
||||
for filename, contents in files:
|
||||
offset = header_length + len(data_buf)
|
||||
file_path = filename.replace("/", "\\").encode('utf-8')
|
||||
out_file.write(struct.pack(
|
||||
f">H{len(file_path)}s2I", len(file_path), file_path, offset, len(contents)
|
||||
))
|
||||
data_buf.extend(contents)
|
||||
|
||||
out_file.write(data_buf)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Loading…
Reference in a new issue