From b2fa4cd5095a98a9c8a65f4e220229d433d25960 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 08:18:21 -0700 Subject: [PATCH] feat(editor): add --unpack-wcp CLI for headless extraction Mirrors --info-wcp / --list-wcp. Default destination is custom_zones/ (matches the GUI's preferred location). With both this and --scaffold-zone, the editor binary can fully bootstrap a zone install without launching the GUI. --- tools/editor/main.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/editor/main.cpp b/tools/editor/main.cpp index 0dbd92e2..c80f8559 100644 --- a/tools/editor/main.cpp +++ b/tools/editor/main.cpp @@ -41,6 +41,7 @@ static void printUsage(const char* argv0) { std::printf(" --info-quests

Print quests.json summary (counts, rewards, chain errors) and exit\n"); std::printf(" --info-wcp Print WCP archive metadata (name, files) and exit\n"); std::printf(" --list-wcp Print every file inside a WCP archive (sorted by path) and exit\n"); + std::printf(" --unpack-wcp [dst] Extract a WCP archive (default dst=custom_zones/) and exit\n"); std::printf(" --version Show version and format info\n\n"); std::printf("Wowee World Editor v1.0.0 — by Kelsi Davis\n"); std::printf("Novel open formats: WOT/WHM/WOM/WOB/WOC/WCP + PNG/JSON\n"); @@ -56,7 +57,7 @@ int main(int argc, char* argv[]) { static const char* kArgRequired[] = { "--data", "--info", "--info-wob", "--info-woc", "--info-wot", "--info-creatures", "--info-objects", "--info-quests", - "--info-wcp", "--list-wcp", "--validate", "--scaffold-zone", + "--info-wcp", "--list-wcp", "--unpack-wcp", "--validate", "--scaffold-zone", "--convert-m2", "--convert-wmo", }; for (int i = 1; i < argc; i++) { @@ -432,6 +433,18 @@ int main(int argc, char* argv[]) { slug.c_str(), slug.c_str()); std::printf(" next step: run editor without args, then File → Open Zone\n"); return 0; + } else if (std::strcmp(argv[i], "--unpack-wcp") == 0 && i + 1 < argc) { + std::string wcpPath = argv[++i]; + std::string destDir = "custom_zones"; + if (i + 1 < argc && argv[i + 1][0] != '-') { + destDir = argv[++i]; + } + if (!wowee::editor::ContentPacker::unpackZone(wcpPath, destDir)) { + std::fprintf(stderr, "WCP unpack failed: %s\n", wcpPath.c_str()); + return 1; + } + std::printf("WCP unpacked to: %s\n", destDir.c_str()); + return 0; } else if (std::strcmp(argv[i], "--list-zones") == 0) { auto zones = wowee::pipeline::CustomZoneDiscovery::scan({"custom_zones", "output"}); if (zones.empty()) {