mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 19:13:52 +00:00
Closes the editing loop on the creature-family catalog: dump a
.wcef to JSON, hand-edit familyKind / petTalentTree /
minLevelForTame / petFoodTypes (e.g. add Bread to Bear's diet,
move Boar from Tenacity to Cunning, drop the tame requirement on
exotic Worm from 50 to 45), re-import to a byte-identical binary.
Three different field types each take dual int+name forms:
- familyKind: int 0..5 OR "beast"/"demon"/"undead"/"elemental"/
"not-pet"/"exotic"
- petTalentTree: int 0..3 OR "none"/"ferocity"/"tenacity"/
"cunning"
- petFoodTypes: int bitfield OR pipe-separated label string
("Meat|Fish|Raw"). Importer prefers the int form when both
are present so unknown bits round-trip losslessly.
Verified byte-identical round-trip on all three presets
(starter / ferocity / exotic). CLI flag count 919 -> 921.
492 lines
19 KiB
C++
492 lines
19 KiB
C++
#include "cli_creature_families_catalog.hpp"
|
|
#include "cli_arg_parse.hpp"
|
|
#include "cli_box_emitter.hpp"
|
|
|
|
#include "pipeline/wowee_creature_families.hpp"
|
|
#include <nlohmann/json.hpp>
|
|
|
|
#include <cctype>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace wowee {
|
|
namespace editor {
|
|
namespace cli {
|
|
|
|
namespace {
|
|
|
|
std::string stripWcefExt(std::string base) {
|
|
stripExt(base, ".wcef");
|
|
return base;
|
|
}
|
|
|
|
bool saveOrError(const wowee::pipeline::WoweeCreatureFamily& c,
|
|
const std::string& base, const char* cmd) {
|
|
if (!wowee::pipeline::WoweeCreatureFamilyLoader::save(c, base)) {
|
|
std::fprintf(stderr, "%s: failed to save %s.wcef\n",
|
|
cmd, base.c_str());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void printGenSummary(const wowee::pipeline::WoweeCreatureFamily& c,
|
|
const std::string& base) {
|
|
std::printf("Wrote %s.wcef\n", base.c_str());
|
|
std::printf(" catalog : %s\n", c.name.c_str());
|
|
std::printf(" families : %zu\n", c.entries.size());
|
|
}
|
|
|
|
int handleGenStarter(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
std::string name = "StarterFamilies";
|
|
if (parseOptArg(i, argc, argv)) name = argv[++i];
|
|
base = stripWcefExt(base);
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::makeStarter(name);
|
|
if (!saveOrError(c, base, "gen-cef")) return 1;
|
|
printGenSummary(c, base);
|
|
return 0;
|
|
}
|
|
|
|
int handleGenFerocity(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
std::string name = "FerocityPets";
|
|
if (parseOptArg(i, argc, argv)) name = argv[++i];
|
|
base = stripWcefExt(base);
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::makeFerocity(name);
|
|
if (!saveOrError(c, base, "gen-cef-ferocity")) return 1;
|
|
printGenSummary(c, base);
|
|
return 0;
|
|
}
|
|
|
|
int handleGenExotic(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
std::string name = "ExoticBeastMaster";
|
|
if (parseOptArg(i, argc, argv)) name = argv[++i];
|
|
base = stripWcefExt(base);
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::makeExotic(name);
|
|
if (!saveOrError(c, base, "gen-cef-exotic")) return 1;
|
|
printGenSummary(c, base);
|
|
return 0;
|
|
}
|
|
|
|
void appendFoodNames(uint32_t flags, std::string& out) {
|
|
using F = wowee::pipeline::WoweeCreatureFamily;
|
|
auto add = [&](const char* n) {
|
|
if (!out.empty()) out += "|";
|
|
out += n;
|
|
};
|
|
if (flags & F::Meat) add("Meat");
|
|
if (flags & F::Fish) add("Fish");
|
|
if (flags & F::Bread) add("Bread");
|
|
if (flags & F::Cheese) add("Cheese");
|
|
if (flags & F::Fruit) add("Fruit");
|
|
if (flags & F::Fungus) add("Fungus");
|
|
if (flags & F::Raw) add("Raw");
|
|
if (out.empty()) out = "-";
|
|
}
|
|
|
|
int handleInfo(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
bool jsonOut = consumeJsonFlag(i, argc, argv);
|
|
base = stripWcefExt(base);
|
|
if (!wowee::pipeline::WoweeCreatureFamilyLoader::exists(base)) {
|
|
std::fprintf(stderr, "WCEF not found: %s.wcef\n", base.c_str());
|
|
return 1;
|
|
}
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::load(base);
|
|
if (jsonOut) {
|
|
nlohmann::json j;
|
|
j["wcef"] = base + ".wcef";
|
|
j["name"] = c.name;
|
|
j["count"] = c.entries.size();
|
|
nlohmann::json arr = nlohmann::json::array();
|
|
for (const auto& e : c.entries) {
|
|
std::string foodNames;
|
|
appendFoodNames(e.petFoodTypes, foodNames);
|
|
arr.push_back({
|
|
{"familyId", e.familyId},
|
|
{"name", e.name},
|
|
{"description", e.description},
|
|
{"familyKind", e.familyKind},
|
|
{"familyKindName", wowee::pipeline::WoweeCreatureFamily::familyKindName(e.familyKind)},
|
|
{"petTalentTree", e.petTalentTree},
|
|
{"petTalentTreeName", wowee::pipeline::WoweeCreatureFamily::petTalentTreeName(e.petTalentTree)},
|
|
{"minLevelForTame", e.minLevelForTame},
|
|
{"skillLine", e.skillLine},
|
|
{"petFoodTypes", e.petFoodTypes},
|
|
{"petFoodTypesLabels", foodNames},
|
|
{"iconColorRGBA", e.iconColorRGBA},
|
|
});
|
|
}
|
|
j["entries"] = arr;
|
|
std::printf("%s\n", j.dump(2).c_str());
|
|
return 0;
|
|
}
|
|
std::printf("WCEF: %s.wcef\n", base.c_str());
|
|
std::printf(" catalog : %s\n", c.name.c_str());
|
|
std::printf(" families : %zu\n", c.entries.size());
|
|
if (c.entries.empty()) return 0;
|
|
std::printf(" id kind tree tameLvl skill foods name\n");
|
|
for (const auto& e : c.entries) {
|
|
std::string foodNames;
|
|
appendFoodNames(e.petFoodTypes, foodNames);
|
|
std::printf(" %4u %-9s %-9s %5u %5u %-30s %s\n",
|
|
e.familyId,
|
|
wowee::pipeline::WoweeCreatureFamily::familyKindName(e.familyKind),
|
|
wowee::pipeline::WoweeCreatureFamily::petTalentTreeName(e.petTalentTree),
|
|
e.minLevelForTame,
|
|
e.skillLine,
|
|
foodNames.c_str(),
|
|
e.name.c_str());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int handleExportJson(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
std::string outPath;
|
|
if (parseOptArg(i, argc, argv)) outPath = argv[++i];
|
|
base = stripWcefExt(base);
|
|
if (!wowee::pipeline::WoweeCreatureFamilyLoader::exists(base)) {
|
|
std::fprintf(stderr,
|
|
"export-wcef-json: WCEF not found: %s.wcef\n",
|
|
base.c_str());
|
|
return 1;
|
|
}
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::load(base);
|
|
if (outPath.empty()) outPath = base + ".wcef.json";
|
|
nlohmann::json j;
|
|
j["catalog"] = c.name;
|
|
nlohmann::json arr = nlohmann::json::array();
|
|
for (const auto& e : c.entries) {
|
|
std::string foodNames;
|
|
appendFoodNames(e.petFoodTypes, foodNames);
|
|
nlohmann::json je;
|
|
je["familyId"] = e.familyId;
|
|
je["name"] = e.name;
|
|
je["description"] = e.description;
|
|
je["familyKind"] = e.familyKind;
|
|
je["familyKindName"] =
|
|
wowee::pipeline::WoweeCreatureFamily::familyKindName(e.familyKind);
|
|
je["petTalentTree"] = e.petTalentTree;
|
|
je["petTalentTreeName"] =
|
|
wowee::pipeline::WoweeCreatureFamily::petTalentTreeName(e.petTalentTree);
|
|
je["minLevelForTame"] = e.minLevelForTame;
|
|
je["skillLine"] = e.skillLine;
|
|
je["petFoodTypes"] = e.petFoodTypes;
|
|
je["petFoodTypesLabels"] = foodNames;
|
|
je["iconColorRGBA"] = e.iconColorRGBA;
|
|
arr.push_back(je);
|
|
}
|
|
j["entries"] = arr;
|
|
std::ofstream os(outPath);
|
|
if (!os) {
|
|
std::fprintf(stderr,
|
|
"export-wcef-json: failed to open %s for write\n",
|
|
outPath.c_str());
|
|
return 1;
|
|
}
|
|
os << j.dump(2) << "\n";
|
|
std::printf("Wrote %s\n", outPath.c_str());
|
|
std::printf(" catalog : %s\n", c.name.c_str());
|
|
std::printf(" families : %zu\n", c.entries.size());
|
|
return 0;
|
|
}
|
|
|
|
uint8_t parseFamilyKindToken(const nlohmann::json& jv,
|
|
uint8_t fallback) {
|
|
if (jv.is_number_integer() || jv.is_number_unsigned()) {
|
|
int v = jv.get<int>();
|
|
if (v < 0 || v > wowee::pipeline::WoweeCreatureFamily::Exotic)
|
|
return fallback;
|
|
return static_cast<uint8_t>(v);
|
|
}
|
|
if (jv.is_string()) {
|
|
std::string s = jv.get<std::string>();
|
|
for (auto& ch : s) ch = static_cast<char>(std::tolower(ch));
|
|
if (s == "beast") return wowee::pipeline::WoweeCreatureFamily::Beast;
|
|
if (s == "demon") return wowee::pipeline::WoweeCreatureFamily::Demon;
|
|
if (s == "undead") return wowee::pipeline::WoweeCreatureFamily::Undead;
|
|
if (s == "elemental") return wowee::pipeline::WoweeCreatureFamily::Elemental;
|
|
if (s == "not-pet" ||
|
|
s == "notpet") return wowee::pipeline::WoweeCreatureFamily::NotPet;
|
|
if (s == "exotic") return wowee::pipeline::WoweeCreatureFamily::Exotic;
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
uint8_t parseTalentTreeToken(const nlohmann::json& jv,
|
|
uint8_t fallback) {
|
|
if (jv.is_number_integer() || jv.is_number_unsigned()) {
|
|
int v = jv.get<int>();
|
|
if (v < 0 || v > wowee::pipeline::WoweeCreatureFamily::Cunning)
|
|
return fallback;
|
|
return static_cast<uint8_t>(v);
|
|
}
|
|
if (jv.is_string()) {
|
|
std::string s = jv.get<std::string>();
|
|
for (auto& ch : s) ch = static_cast<char>(std::tolower(ch));
|
|
if (s == "none") return wowee::pipeline::WoweeCreatureFamily::TreeNone;
|
|
if (s == "ferocity") return wowee::pipeline::WoweeCreatureFamily::Ferocity;
|
|
if (s == "tenacity") return wowee::pipeline::WoweeCreatureFamily::Tenacity;
|
|
if (s == "cunning") return wowee::pipeline::WoweeCreatureFamily::Cunning;
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
uint32_t parseFoodTypesField(const nlohmann::json& jv) {
|
|
using F = wowee::pipeline::WoweeCreatureFamily;
|
|
if (jv.is_number_integer() || jv.is_number_unsigned())
|
|
return jv.get<uint32_t>();
|
|
if (jv.is_string()) {
|
|
std::string s = jv.get<std::string>();
|
|
uint32_t out = 0;
|
|
size_t pos = 0;
|
|
while (pos < s.size()) {
|
|
size_t end = s.find('|', pos);
|
|
if (end == std::string::npos) end = s.size();
|
|
std::string tok = s.substr(pos, end - pos);
|
|
for (auto& ch : tok) ch = static_cast<char>(std::tolower(ch));
|
|
if (tok == "meat") out |= F::Meat;
|
|
else if (tok == "fish") out |= F::Fish;
|
|
else if (tok == "bread") out |= F::Bread;
|
|
else if (tok == "cheese") out |= F::Cheese;
|
|
else if (tok == "fruit") out |= F::Fruit;
|
|
else if (tok == "fungus") out |= F::Fungus;
|
|
else if (tok == "raw") out |= F::Raw;
|
|
pos = end + 1;
|
|
}
|
|
return out;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int handleImportJson(int& i, int argc, char** argv) {
|
|
std::string jsonPath = argv[++i];
|
|
std::string outBase;
|
|
if (parseOptArg(i, argc, argv)) outBase = argv[++i];
|
|
std::ifstream is(jsonPath);
|
|
if (!is) {
|
|
std::fprintf(stderr,
|
|
"import-wcef-json: failed to open %s\n", jsonPath.c_str());
|
|
return 1;
|
|
}
|
|
nlohmann::json j;
|
|
try {
|
|
is >> j;
|
|
} catch (const std::exception& ex) {
|
|
std::fprintf(stderr,
|
|
"import-wcef-json: parse error in %s: %s\n",
|
|
jsonPath.c_str(), ex.what());
|
|
return 1;
|
|
}
|
|
wowee::pipeline::WoweeCreatureFamily c;
|
|
if (j.contains("catalog") && j["catalog"].is_string())
|
|
c.name = j["catalog"].get<std::string>();
|
|
if (j.contains("entries") && j["entries"].is_array()) {
|
|
for (const auto& je : j["entries"]) {
|
|
wowee::pipeline::WoweeCreatureFamily::Entry e;
|
|
if (je.contains("familyId")) e.familyId = je["familyId"].get<uint32_t>();
|
|
if (je.contains("name")) e.name = je["name"].get<std::string>();
|
|
if (je.contains("description")) e.description = je["description"].get<std::string>();
|
|
uint8_t kind = wowee::pipeline::WoweeCreatureFamily::Beast;
|
|
if (je.contains("familyKind"))
|
|
kind = parseFamilyKindToken(je["familyKind"], kind);
|
|
else if (je.contains("familyKindName"))
|
|
kind = parseFamilyKindToken(je["familyKindName"], kind);
|
|
e.familyKind = kind;
|
|
uint8_t tree = wowee::pipeline::WoweeCreatureFamily::TreeNone;
|
|
if (je.contains("petTalentTree"))
|
|
tree = parseTalentTreeToken(je["petTalentTree"], tree);
|
|
else if (je.contains("petTalentTreeName"))
|
|
tree = parseTalentTreeToken(je["petTalentTreeName"], tree);
|
|
e.petTalentTree = tree;
|
|
if (je.contains("minLevelForTame"))
|
|
e.minLevelForTame = je["minLevelForTame"].get<uint8_t>();
|
|
if (je.contains("skillLine"))
|
|
e.skillLine = je["skillLine"].get<uint32_t>();
|
|
if (je.contains("petFoodTypes"))
|
|
e.petFoodTypes = parseFoodTypesField(je["petFoodTypes"]);
|
|
else if (je.contains("petFoodTypesLabels"))
|
|
e.petFoodTypes = parseFoodTypesField(je["petFoodTypesLabels"]);
|
|
if (je.contains("iconColorRGBA"))
|
|
e.iconColorRGBA = je["iconColorRGBA"].get<uint32_t>();
|
|
c.entries.push_back(e);
|
|
}
|
|
}
|
|
if (outBase.empty()) {
|
|
outBase = jsonPath;
|
|
const std::string suffix1 = ".wcef.json";
|
|
const std::string suffix2 = ".json";
|
|
if (outBase.size() >= suffix1.size() &&
|
|
outBase.compare(outBase.size() - suffix1.size(),
|
|
suffix1.size(), suffix1) == 0) {
|
|
outBase.resize(outBase.size() - suffix1.size());
|
|
} else if (outBase.size() >= suffix2.size() &&
|
|
outBase.compare(outBase.size() - suffix2.size(),
|
|
suffix2.size(), suffix2) == 0) {
|
|
outBase.resize(outBase.size() - suffix2.size());
|
|
}
|
|
}
|
|
outBase = stripWcefExt(outBase);
|
|
if (!wowee::pipeline::WoweeCreatureFamilyLoader::save(c, outBase)) {
|
|
std::fprintf(stderr,
|
|
"import-wcef-json: failed to save %s.wcef\n",
|
|
outBase.c_str());
|
|
return 1;
|
|
}
|
|
std::printf("Wrote %s.wcef\n", outBase.c_str());
|
|
std::printf(" catalog : %s\n", c.name.c_str());
|
|
std::printf(" families : %zu\n", c.entries.size());
|
|
return 0;
|
|
}
|
|
|
|
int handleValidate(int& i, int argc, char** argv) {
|
|
std::string base = argv[++i];
|
|
bool jsonOut = consumeJsonFlag(i, argc, argv);
|
|
base = stripWcefExt(base);
|
|
if (!wowee::pipeline::WoweeCreatureFamilyLoader::exists(base)) {
|
|
std::fprintf(stderr,
|
|
"validate-wcef: WCEF not found: %s.wcef\n", base.c_str());
|
|
return 1;
|
|
}
|
|
auto c = wowee::pipeline::WoweeCreatureFamilyLoader::load(base);
|
|
std::vector<std::string> errors;
|
|
std::vector<std::string> warnings;
|
|
if (c.entries.empty()) {
|
|
warnings.push_back("catalog has zero entries");
|
|
}
|
|
std::vector<uint32_t> idsSeen;
|
|
constexpr uint32_t kKnownFoodMask =
|
|
wowee::pipeline::WoweeCreatureFamily::Meat |
|
|
wowee::pipeline::WoweeCreatureFamily::Fish |
|
|
wowee::pipeline::WoweeCreatureFamily::Bread |
|
|
wowee::pipeline::WoweeCreatureFamily::Cheese |
|
|
wowee::pipeline::WoweeCreatureFamily::Fruit |
|
|
wowee::pipeline::WoweeCreatureFamily::Fungus |
|
|
wowee::pipeline::WoweeCreatureFamily::Raw;
|
|
for (size_t k = 0; k < c.entries.size(); ++k) {
|
|
const auto& e = c.entries[k];
|
|
std::string ctx = "entry " + std::to_string(k) +
|
|
" (id=" + std::to_string(e.familyId);
|
|
if (!e.name.empty()) ctx += " " + e.name;
|
|
ctx += ")";
|
|
if (e.familyId == 0)
|
|
errors.push_back(ctx + ": familyId is 0");
|
|
if (e.name.empty())
|
|
errors.push_back(ctx + ": name is empty");
|
|
if (e.familyKind > wowee::pipeline::WoweeCreatureFamily::Exotic) {
|
|
errors.push_back(ctx + ": familyKind " +
|
|
std::to_string(e.familyKind) + " not in 0..5");
|
|
}
|
|
if (e.petTalentTree > wowee::pipeline::WoweeCreatureFamily::Cunning) {
|
|
errors.push_back(ctx + ": petTalentTree " +
|
|
std::to_string(e.petTalentTree) + " not in 0..3");
|
|
}
|
|
if (e.petFoodTypes & ~kKnownFoodMask) {
|
|
warnings.push_back(ctx +
|
|
": petFoodTypes has bits outside known mask " +
|
|
"(0x" + std::to_string(e.petFoodTypes & ~kKnownFoodMask) +
|
|
") — engine will ignore unknown food types");
|
|
}
|
|
// NotPet families should not specify a talent tree —
|
|
// confusing if they do.
|
|
if (e.familyKind == wowee::pipeline::WoweeCreatureFamily::NotPet &&
|
|
e.petTalentTree != wowee::pipeline::WoweeCreatureFamily::TreeNone) {
|
|
warnings.push_back(ctx +
|
|
": NotPet family with petTalentTree=" +
|
|
wowee::pipeline::WoweeCreatureFamily::petTalentTreeName(e.petTalentTree) +
|
|
" — talent tree is irrelevant for non-pet kinds");
|
|
}
|
|
// Exotic families above level 80 won't be tamable
|
|
// by anyone (level cap).
|
|
if (e.familyKind == wowee::pipeline::WoweeCreatureFamily::Exotic &&
|
|
e.minLevelForTame > 80) {
|
|
warnings.push_back(ctx +
|
|
": Exotic family with minLevelForTame=" +
|
|
std::to_string(e.minLevelForTame) +
|
|
" > 80 — no hunter can reach this level");
|
|
}
|
|
// Pet kinds with no food types set means they can't
|
|
// be fed — common bug, especially for hand-edited
|
|
// sidecars.
|
|
if ((e.familyKind == wowee::pipeline::WoweeCreatureFamily::Beast ||
|
|
e.familyKind == wowee::pipeline::WoweeCreatureFamily::Exotic) &&
|
|
e.petFoodTypes == 0) {
|
|
warnings.push_back(ctx +
|
|
": pet-able family with no food types set — "
|
|
"hunter pet will starve, no food will satisfy it");
|
|
}
|
|
for (uint32_t prev : idsSeen) {
|
|
if (prev == e.familyId) {
|
|
errors.push_back(ctx + ": duplicate familyId");
|
|
break;
|
|
}
|
|
}
|
|
idsSeen.push_back(e.familyId);
|
|
}
|
|
bool ok = errors.empty();
|
|
if (jsonOut) {
|
|
nlohmann::json j;
|
|
j["wcef"] = base + ".wcef";
|
|
j["ok"] = ok;
|
|
j["errors"] = errors;
|
|
j["warnings"] = warnings;
|
|
std::printf("%s\n", j.dump(2).c_str());
|
|
return ok ? 0 : 1;
|
|
}
|
|
std::printf("validate-wcef: %s.wcef\n", base.c_str());
|
|
if (ok && warnings.empty()) {
|
|
std::printf(" OK — %zu families, all familyIds unique\n",
|
|
c.entries.size());
|
|
return 0;
|
|
}
|
|
if (!warnings.empty()) {
|
|
std::printf(" warnings (%zu):\n", warnings.size());
|
|
for (const auto& w : warnings)
|
|
std::printf(" - %s\n", w.c_str());
|
|
}
|
|
if (!errors.empty()) {
|
|
std::printf(" ERRORS (%zu):\n", errors.size());
|
|
for (const auto& e : errors)
|
|
std::printf(" - %s\n", e.c_str());
|
|
}
|
|
return ok ? 0 : 1;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
bool handleCreatureFamiliesCatalog(int& i, int argc, char** argv,
|
|
int& outRc) {
|
|
if (std::strcmp(argv[i], "--gen-cef") == 0 && i + 1 < argc) {
|
|
outRc = handleGenStarter(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--gen-cef-ferocity") == 0 && i + 1 < argc) {
|
|
outRc = handleGenFerocity(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--gen-cef-exotic") == 0 && i + 1 < argc) {
|
|
outRc = handleGenExotic(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--info-wcef") == 0 && i + 1 < argc) {
|
|
outRc = handleInfo(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--validate-wcef") == 0 && i + 1 < argc) {
|
|
outRc = handleValidate(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--export-wcef-json") == 0 && i + 1 < argc) {
|
|
outRc = handleExportJson(i, argc, argv); return true;
|
|
}
|
|
if (std::strcmp(argv[i], "--import-wcef-json") == 0 && i + 1 < argc) {
|
|
outRc = handleImportJson(i, argc, argv); return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace cli
|
|
} // namespace editor
|
|
} // namespace wowee
|