aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorきゃれい <[email protected]>2017-08-16 03:10:31 +0000
committerきゃれい <[email protected]>2017-08-16 03:10:31 +0000
commit1a824b3ed577ad99a3c4b6671e3e871079633d75 (patch)
tree3763caf7353a98f8e93fae9dbb490dd6d293fb18
parentFix jankiness when repacker chooses not to compress a non-blacklisted file (diff)
downloadkiwad-repacker-master.tar.xz
kiwad-repacker-master.zip
Fix for Windows – replace backslashes with forward slashes beforeHEADmaster
saving as entry
-rw-r--r--repack.py257
1 files changed, 129 insertions, 128 deletions
diff --git a/repack.py b/repack.py
index c566a59..2b37bba 100644
--- a/repack.py
+++ b/repack.py
@@ -1,128 +1,129 @@
-#!/usr/bin/env python3
-
-import argparse
-import io
-import pathlib
-import re
-import zlib
-
-# The MIT License (MIT)
-# Copyright (c) 2016 kyarei
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy of
-# this software and associated documentation files (the "Software"), to deal in
-# the Software without restriction, including without limitation the rights to
-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-# of the Software, and to permit persons to whom the Software is furnished to do
-# so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-
-# Usage: python3 repack.py <root dir> <archive name>
-
-# Parse the arguments
-
-parser = argparse.ArgumentParser(description='Repack Wizard101 WAD files.')
-parser.add_argument('sourcePath', type=str,
- help='the root directory of the files to be archived')
-parser.add_argument('archivePath', type=str,
- help='the path of the archive file to be made')
-parser.add_argument('blacklist', type=str, nargs='?', default='',
- help='a file containing patterns to avoid compressing')
-parser.add_argument('--verbose', '-v', type=bool,
- help='if enabled, use diagnostics')
-
-args = parser.parse_args()
-
-# Get all files in the directory specified
-
-root = pathlib.Path(args.sourcePath)
-files = root.glob("**/*");
-blacklist = set()
-if args.blacklist != '':
- blacklistPatterns = re.split('\s', open(args.blacklist).read(-1))
- for p in blacklistPatterns:
- if p != '':
- blacklist.update(set(root.glob(p)))
-entries = []
-offset = 14 # Precalculate offset of data section in loop below
-
-# Make entries of all files
-
-for f in files:
- if f.is_file():
- with f.open(mode="rb") as h:
- contents = h.read(-1)
- isCompressed = not f in blacklist
- zSize = 0xFFFFFFFF
- uSize = len(contents)
- if isCompressed:
- compressedContents = zlib.compress(contents)
- zSize = len(compressedContents)
- isCompressed = zSize < uSize
- name = str(f.relative_to(root))
- crc = zlib.crc32(contents)
- entry = {
- "contents": compressedContents if isCompressed else contents,
- "uSize": uSize,
- "zSize": zSize,
- "name": name,
- "isCompressed": isCompressed,
- "crc": crc
- }
- entries.append(entry)
- offset += 22 + len(name)
- if args.verbose:
- print("> File %s acknowledged" % name)
-
-if args.verbose:
- print("%d files acknowledged" % len(entries))
-
-# Open the output file
-
-out = open(args.archivePath, "wb");
-
-def writeByte(stream, val):
- stream.write(bytes([val]))
-def writeInt(stream, val):
- stream.write(val.to_bytes(4, byteorder="little"))
-
-if args.verbose:
- print("Opened output file; writing data...")
-
-# Write magic string
-out.write(b"KIWAD")
-# Write version
-writeInt(out, 2)
-# Write number of files
-writeInt(out, len(entries))
-# Write dummy byte
-writeByte(out, 1)
-# Write file ENTRIES
-for e in entries:
- netSize = e["zSize"] if e["isCompressed"] else e["uSize"]
- writeInt(out, offset) # Offset
- writeInt(out, e["uSize"])
- writeInt(out, e["zSize"])
- writeByte(out, e["isCompressed"])
- writeInt(out, e["crc"])
- writeInt(out, len(e["name"].encode()) + 1) # includes terminating null
- out.write(e["name"].encode())
- writeByte(out, 0)
- offset += netSize
- if args.verbose:
- print("> Wrote ENTRY for %s" % e["name"])
-# Write file DATA
-for e in entries:
- out.write(e["contents"])
- if args.verbose:
- print("> Wrote DATA for %s" % e["name"])
+#!/usr/bin/env python3
+
+import argparse
+import io
+import pathlib
+import re
+import zlib
+
+# The MIT License (MIT)
+# Copyright (c) 2016 kyarei
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# Usage: python3 repack.py <root dir> <archive name>
+
+# Parse the arguments
+
+parser = argparse.ArgumentParser(description='Repack Wizard101 WAD files.')
+parser.add_argument('sourcePath', type=str,
+ help='the root directory of the files to be archived')
+parser.add_argument('archivePath', type=str,
+ help='the path of the archive file to be made')
+parser.add_argument('blacklist', type=str, nargs='?', default='',
+ help='a file containing patterns to avoid compressing')
+parser.add_argument('--verbose', '-v', type=bool,
+ help='if enabled, use diagnostics')
+
+args = parser.parse_args()
+
+# Get all files in the directory specified
+
+root = pathlib.Path(args.sourcePath)
+files = root.glob("**/*");
+blacklist = set()
+if args.blacklist != '':
+ blacklistPatterns = re.split('\s', open(args.blacklist).read(-1))
+ for p in blacklistPatterns:
+ if p != '':
+ blacklist.update(set(root.glob(p)))
+entries = []
+offset = 14 # Precalculate offset of data section in loop below
+
+# Make entries of all files
+
+for f in files:
+ if f.is_file():
+ with f.open(mode="rb") as h:
+ contents = h.read(-1)
+ isCompressed = not f in blacklist
+ zSize = 0xFFFFFFFF
+ uSize = len(contents)
+ if isCompressed:
+ compressedContents = zlib.compress(contents)
+ zSize = len(compressedContents)
+ isCompressed = zSize < uSize
+ name = str(f.relative_to(root))
+ name = name.replace("\\", "/")
+ crc = zlib.crc32(contents)
+ entry = {
+ "contents": compressedContents if isCompressed else contents,
+ "uSize": uSize,
+ "zSize": zSize,
+ "name": name,
+ "isCompressed": isCompressed,
+ "crc": crc
+ }
+ entries.append(entry)
+ offset += 22 + len(name)
+ if args.verbose:
+ print("> File %s acknowledged" % name)
+
+if args.verbose:
+ print("%d files acknowledged" % len(entries))
+
+# Open the output file
+
+out = open(args.archivePath, "wb");
+
+def writeByte(stream, val):
+ stream.write(bytes([val]))
+def writeInt(stream, val):
+ stream.write(val.to_bytes(4, byteorder="little"))
+
+if args.verbose:
+ print("Opened output file; writing data...")
+
+# Write magic string
+out.write(b"KIWAD")
+# Write version
+writeInt(out, 2)
+# Write number of files
+writeInt(out, len(entries))
+# Write dummy byte
+writeByte(out, 1)
+# Write file ENTRIES
+for e in entries:
+ netSize = e["zSize"] if e["isCompressed"] else e["uSize"]
+ writeInt(out, offset) # Offset
+ writeInt(out, e["uSize"])
+ writeInt(out, e["zSize"])
+ writeByte(out, e["isCompressed"])
+ writeInt(out, e["crc"])
+ writeInt(out, len(e["name"].encode()) + 1) # includes terminating null
+ out.write(e["name"].encode())
+ writeByte(out, 0)
+ offset += netSize
+ if args.verbose:
+ print("> Wrote ENTRY for %s" % e["name"])
+# Write file DATA
+for e in entries:
+ out.write(e["contents"])
+ if args.verbose:
+ print("> Wrote DATA for %s" % e["name"])