import argparse, os, struct, csv, sys def align16(x): return (x + 15) & ~15 def collect(args): items = [] if args.csv and os.path.exists(args.csv): with open(args.csv, newline="", encoding="utf-8") as f: for row in csv.DictReader(f): items.append((row["name"], row["file"])) else: for root, dirs, files in os.walk(args.dir): for fn in files: full = os.path.join(root, fn) rel = os.path.relpath(full, args.dir) name = rel.replace("/", "\\") items.append((name, rel)) return items def main(): ap = argparse.ArgumentParser(description="Rebuild a Dragon .res archive from a directory (16-byte aligned blobs).") ap.add_argument("dir") ap.add_argument("out") ap.add_argument("--csv", default=None) args = ap.parse_args() items = collect(args) blobs = [] for name, rel in items: full = os.path.join(args.dir, rel) if not os.path.isfile(full): print("missing: %s" % full, file=sys.stderr) sys.exit(2) blobs.append((name, open(full, "rb").read())) hdr = 4 for name, _ in blobs: hdr += 4 + len(name) + 8 data_start = align16(hdr) out = bytearray() out += struct.pack(" %s (%d bytes)" % (len(blobs), args.out, len(out))) if __name__ == "__main__": main()