mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-07 09:33:51 +00:00
feat(editor): add --diff-jsondbc completing the diff family for the last text format
Diff family is now exhaustively complete across every shippable format: --diff-wcp archive --diff-zone unpacked zone dir --diff-glb glTF binary --diff-wom WOM model --diff-wob WOB building --diff-whm WHM/WOT terrain pair --diff-woc WOC collision --diff-jsondbc JSON DBC sidecar <- new Schema-level compare: - format tag - source filename - recordCount + fieldCount (header values) - actualRecs (records[] array length) Useful for catching schema regressions when a sidecar is regenerated by a different tool version, or for verifying a --migrate-jsondbc pass actually changed what it claimed. Verified: same file vs itself reports IDENTICAL exit 0; 2-record vs 3-record (with same format/source/fieldCount) reports 2 DIFFs (recordCount + actualRecs) with exit 1.
This commit is contained in:
parent
e531901de8
commit
84f897f0ec
1 changed files with 84 additions and 0 deletions
|
|
@ -620,6 +620,8 @@ static void printUsage(const char* argv0) {
|
|||
std::printf(" Compare two WHM/WOT terrain pairs (chunks, height range, placements)\n");
|
||||
std::printf(" --diff-woc <a> <b> [--json]\n");
|
||||
std::printf(" Compare two WOC collision meshes (triangles, walkable/steep counts, tile)\n");
|
||||
std::printf(" --diff-jsondbc <a> <b> [--json]\n");
|
||||
std::printf(" Compare two JSON DBC sidecars (format/source/recordCount/fieldCount)\n");
|
||||
std::printf(" --pack-wcp <zone> [dst] Pack a zone dir/name into a .wcp archive and exit\n");
|
||||
std::printf(" --unpack-wcp <wcp> [dst] Extract a WCP archive (default dst=custom_zones/) and exit\n");
|
||||
std::printf(" --list-commands Print every recognized --flag, one per line, and exit\n");
|
||||
|
|
@ -719,6 +721,11 @@ int main(int argc, char* argv[]) {
|
|||
"--diff-woc requires <a.woc> <b.woc>\n");
|
||||
return 1;
|
||||
}
|
||||
if (std::strcmp(argv[i], "--diff-jsondbc") == 0 && i + 2 >= argc) {
|
||||
std::fprintf(stderr,
|
||||
"--diff-jsondbc requires <a.json> <b.json>\n");
|
||||
return 1;
|
||||
}
|
||||
if (std::strcmp(argv[i], "--diff-wcp") == 0 && i + 2 >= argc) {
|
||||
std::fprintf(stderr, "--diff-wcp requires two paths\n");
|
||||
return 1;
|
||||
|
|
@ -3453,6 +3460,83 @@ int main(int argc, char* argv[]) {
|
|||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (std::strcmp(argv[i], "--diff-jsondbc") == 0 && i + 2 < argc) {
|
||||
// JSON DBC structural diff. Catches schema regressions when
|
||||
// a sidecar is regenerated by a different tool version (or
|
||||
// a different DBC layout produces a different field count).
|
||||
std::string aPath = argv[++i];
|
||||
std::string bPath = argv[++i];
|
||||
bool jsonOut = (i + 1 < argc &&
|
||||
std::strcmp(argv[i + 1], "--json") == 0);
|
||||
if (jsonOut) i++;
|
||||
auto loadDoc = [](const std::string& p, nlohmann::json& doc) {
|
||||
std::ifstream in(p);
|
||||
if (!in) return false;
|
||||
try { in >> doc; } catch (...) { return false; }
|
||||
return true;
|
||||
};
|
||||
nlohmann::json a, b;
|
||||
if (!loadDoc(aPath, a)) {
|
||||
std::fprintf(stderr, "diff-jsondbc: failed to read %s\n", aPath.c_str());
|
||||
return 1;
|
||||
}
|
||||
if (!loadDoc(bPath, b)) {
|
||||
std::fprintf(stderr, "diff-jsondbc: failed to read %s\n", bPath.c_str());
|
||||
return 1;
|
||||
}
|
||||
// Pull comparable fields with safe defaults.
|
||||
std::string aFmt = a.value("format", std::string{});
|
||||
std::string bFmt = b.value("format", std::string{});
|
||||
std::string aSrc = a.value("source", std::string{});
|
||||
std::string bSrc = b.value("source", std::string{});
|
||||
uint32_t aRC = a.value("recordCount", 0u);
|
||||
uint32_t bRC = b.value("recordCount", 0u);
|
||||
uint32_t aFC = a.value("fieldCount", 0u);
|
||||
uint32_t bFC = b.value("fieldCount", 0u);
|
||||
uint32_t aActual = (a.contains("records") && a["records"].is_array())
|
||||
? static_cast<uint32_t>(a["records"].size()) : 0u;
|
||||
uint32_t bActual = (b.contains("records") && b["records"].is_array())
|
||||
? static_cast<uint32_t>(b["records"].size()) : 0u;
|
||||
int diffs = 0;
|
||||
if (aFmt != bFmt) diffs++;
|
||||
if (aSrc != bSrc) diffs++;
|
||||
if (aRC != bRC) diffs++;
|
||||
if (aFC != bFC) diffs++;
|
||||
if (aActual != bActual) diffs++;
|
||||
if (jsonOut) {
|
||||
nlohmann::json j;
|
||||
j["a"] = aPath; j["b"] = bPath;
|
||||
j["format"] = {{"a", aFmt}, {"b", bFmt}};
|
||||
j["source"] = {{"a", aSrc}, {"b", bSrc}};
|
||||
j["recordCount"] = {{"a", aRC}, {"b", bRC}};
|
||||
j["fieldCount"] = {{"a", aFC}, {"b", bFC}};
|
||||
j["actualRecs"] = {{"a", aActual}, {"b", bActual}};
|
||||
j["totalDiffs"] = diffs;
|
||||
j["identical"] = (diffs == 0);
|
||||
std::printf("%s\n", j.dump(2).c_str());
|
||||
return diffs == 0 ? 0 : 1;
|
||||
}
|
||||
auto cmpStr = [](const char* lbl, const std::string& a, const std::string& b) {
|
||||
std::printf(" %-12s: %-20s %-20s %s\n", lbl,
|
||||
a.empty() ? "(unset)" : a.c_str(),
|
||||
b.empty() ? "(unset)" : b.c_str(),
|
||||
a == b ? "" : "DIFF");
|
||||
};
|
||||
auto cmpNum = [](const char* lbl, uint32_t a, uint32_t b) {
|
||||
std::printf(" %-12s: %20u %20u %s\n", lbl, a, b,
|
||||
a == b ? "" : "DIFF");
|
||||
};
|
||||
std::printf("Diff: %s vs %s\n", aPath.c_str(), bPath.c_str());
|
||||
cmpStr("format", aFmt, bFmt);
|
||||
cmpStr("source", aSrc, bSrc);
|
||||
cmpNum("recordCount", aRC, bRC);
|
||||
cmpNum("fieldCount", aFC, bFC);
|
||||
cmpNum("actualRecs", aActual, bActual);
|
||||
if (diffs == 0) {
|
||||
std::printf(" IDENTICAL\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
} else if (std::strcmp(argv[i], "--list-wcp") == 0 && i + 1 < argc) {
|
||||
// Like --info-wcp but prints every file path. Useful for spotting
|
||||
// missing or unexpected entries before unpacking.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue