mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-07 17:43:51 +00:00
feat(editor): add --info-pack-budget for per-extension WCP byte breakdown
Where --info-wcp shows file counts per category, this drills into
per-extension byte costs so users can spot what's bloating an
archive before shipping:
wowee_editor --info-pack-budget custom_zones/MyZone.wcp
WCP budget: custom_zones/MyZone.wcp
total: 47 file(s), 2.34 MB
ext count bytes KB share
.whm 4 1683456 1644.0 70.3%
.wob 3 451200 440.6 18.8%
.wom 12 163840 160.0 6.8%
.json 8 85120 83.1 3.6%
.woc 1 12672 12.4 0.5%
Sorted by bytes descending so the heaviest contributors surface
first. Useful for:
- Spotting accidental .glb/.obj inclusion in shipping packs
(`--pack-wcp` should run after `--strip-zone` to keep
derived outputs out)
- Capacity budgeting when targeting a max-pack-size
- Comparing pre/post compression ratios
Pairs with --info-wcp (counts), --list-wcp (full file list),
--diff-wcp (compare two packs), --info-pack-budget (this one,
byte costs).
Verified on a freshly-mvp-zone packed WCP: 6 files / 0.17 MB
correctly broken down (whm 84%, wot 14.9%, json 1.1%).
This commit is contained in:
parent
baf54d5e47
commit
1797ffd280
1 changed files with 68 additions and 1 deletions
|
|
@ -740,6 +740,8 @@ static void printUsage(const char* argv0) {
|
|||
std::printf(" Print every field for one object placement (type, path, transform)\n");
|
||||
std::printf(" --info-wcp <wcp-path> [--json]\n");
|
||||
std::printf(" Print WCP archive metadata (name, files) and exit\n");
|
||||
std::printf(" --info-pack-budget <wcp-path> [--json]\n");
|
||||
std::printf(" Per-extension byte breakdown of a WCP archive (sized largest-first)\n");
|
||||
std::printf(" --list-wcp <wcp-path> Print every file inside a WCP archive (sorted by path) and exit\n");
|
||||
std::printf(" --diff-wcp <a> <b> [--json]\n");
|
||||
std::printf(" Compare two WCPs file-by-file; exit 0 if identical, 1 otherwise\n");
|
||||
|
|
@ -791,7 +793,7 @@ int main(int argc, char* argv[]) {
|
|||
"--info-wob", "--info-woc", "--info-wot",
|
||||
"--info-creatures", "--info-objects", "--info-quests",
|
||||
"--info-extract", "--info-extract-tree", "--list-missing-sidecars",
|
||||
"--info-png", "--info-jsondbc", "--info-blp",
|
||||
"--info-png", "--info-jsondbc", "--info-blp", "--info-pack-budget",
|
||||
"--info-m2", "--info-wmo", "--info-adt",
|
||||
"--info-zone", "--info-wcp", "--list-wcp",
|
||||
"--list-creatures", "--list-objects", "--list-quests",
|
||||
|
|
@ -4205,6 +4207,71 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
std::printf(" total bytes : %.2f MB\n", totalSize / (1024.0 * 1024.0));
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--info-pack-budget") == 0 && i + 1 < argc) {
|
||||
// Per-extension byte breakdown of a WCP archive. --info-wcp
|
||||
// gives counts per category; this gives bytes per extension
|
||||
// so users can spot what's bloating an archive before
|
||||
// shipping. ('Why is my pack 80MB? Oh, the .glb baked
|
||||
// outputs got included.')
|
||||
std::string path = argv[++i];
|
||||
bool jsonOut = (i + 1 < argc &&
|
||||
std::strcmp(argv[i + 1], "--json") == 0);
|
||||
if (jsonOut) i++;
|
||||
wowee::editor::ContentPackInfo info;
|
||||
if (!wowee::editor::ContentPacker::readInfo(path, info)) {
|
||||
std::fprintf(stderr,
|
||||
"info-pack-budget: failed to read %s\n", path.c_str());
|
||||
return 1;
|
||||
}
|
||||
// Sum bytes per extension (lower-cased).
|
||||
std::map<std::string, std::pair<int, uint64_t>> byExt;
|
||||
uint64_t totalBytes = 0;
|
||||
for (const auto& f : info.files) {
|
||||
std::string ext;
|
||||
auto dot = f.path.find_last_of('.');
|
||||
if (dot != std::string::npos) ext = f.path.substr(dot);
|
||||
else ext = "(no-ext)";
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
byExt[ext].first++;
|
||||
byExt[ext].second += f.size;
|
||||
totalBytes += f.size;
|
||||
}
|
||||
// Sort by bytes descending.
|
||||
std::vector<std::pair<std::string, std::pair<int, uint64_t>>> sorted(
|
||||
byExt.begin(), byExt.end());
|
||||
std::sort(sorted.begin(), sorted.end(),
|
||||
[](const auto& a, const auto& b) {
|
||||
return a.second.second > b.second.second;
|
||||
});
|
||||
if (jsonOut) {
|
||||
nlohmann::json j;
|
||||
j["wcp"] = path;
|
||||
j["totalFiles"] = info.files.size();
|
||||
j["totalBytes"] = totalBytes;
|
||||
nlohmann::json arr = nlohmann::json::array();
|
||||
for (const auto& [ext, cb] : sorted) {
|
||||
arr.push_back({{"ext", ext},
|
||||
{"count", cb.first},
|
||||
{"bytes", cb.second}});
|
||||
}
|
||||
j["byExtension"] = arr;
|
||||
std::printf("%s\n", j.dump(2).c_str());
|
||||
return 0;
|
||||
}
|
||||
std::printf("WCP budget: %s\n", path.c_str());
|
||||
std::printf(" total: %zu file(s), %.2f MB\n",
|
||||
info.files.size(), totalBytes / (1024.0 * 1024.0));
|
||||
std::printf("\n ext count bytes KB share\n");
|
||||
for (const auto& [ext, cb] : sorted) {
|
||||
double pct = totalBytes > 0
|
||||
? 100.0 * cb.second / totalBytes : 0.0;
|
||||
std::printf(" %-12s %6d %11llu %6.1f %5.1f%%\n",
|
||||
ext.c_str(), cb.first,
|
||||
static_cast<unsigned long long>(cb.second),
|
||||
cb.second / 1024.0, pct);
|
||||
}
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--info-wot") == 0 && i + 1 < argc) {
|
||||
std::string base = argv[++i];
|
||||
bool jsonOut = (i + 1 < argc &&
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue