1
0
Files
libcmo21/Ballance/BMapInspector/BMapInspector.cpp

153 lines
4.7 KiB
C++
Raw Normal View History

2026-01-30 20:23:39 +08:00
#include "Utils.hpp"
#include "Reporter.hpp"
2026-02-02 14:17:31 +08:00
#include "Cli.hpp"
#include "Map.hpp"
#include "Rule.hpp"
2026-01-30 20:23:39 +08:00
#include <VTAll.hpp>
#include <yycc.hpp>
#include <yycc/carton/termcolor.hpp>
2026-01-30 20:40:21 +08:00
#include <yycc/string/op.hpp>
2026-01-30 20:23:39 +08:00
#include <yycc/patch/stream.hpp>
#include <iostream>
2026-01-31 23:16:50 +08:00
#include <optional>
2026-01-30 20:23:39 +08:00
using namespace yycc::patch::stream;
2026-01-30 20:40:21 +08:00
namespace strop = yycc::string::op;
2026-01-30 20:23:39 +08:00
namespace termcolor = yycc::carton::termcolor;
using termcolor::Color;
2026-01-31 23:16:50 +08:00
static void PrintSplash() {
std::cout << termcolor::colored(u8"" BMAPINSP_NAME, Color::LightYellow)
2026-01-31 23:16:50 +08:00
<< " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl
<< u8"" BMAPINSP_DESC << std::endl;
}
2026-01-31 23:16:50 +08:00
static std::optional<BMapInspector::Cli::Args> AcceptArgs() {
auto request = BMapInspector::Cli::parse();
if (request.has_value()) {
2026-02-02 14:17:31 +08:00
return std::move(request.value());
2026-01-31 23:16:50 +08:00
} else {
using BMapInspector::Cli::Error;
std::u8string err_words;
2026-01-31 23:16:50 +08:00
switch (request.error()) {
case Error::BadParse:
err_words = u8"Can not parse given command line argument.";
break;
case Error::NoFile:
err_words = u8"You must specify a file for checking.";
2026-01-31 23:16:50 +08:00
break;
case Error::BadFile:
err_words = u8"Your specified file is invalid.";
2026-01-31 23:16:50 +08:00
break;
case Error::NoBallance:
err_words = u8"You must specify Ballance root directory for finding resources.";
2026-01-31 23:16:50 +08:00
break;
case Error::BadBallance:
err_words = u8"Your specified Ballance root directory is invalid.";
2026-01-31 23:16:50 +08:00
break;
case Error::BadEncoding:
err_words = u8"Your specified encoding name is invalid.";
2026-01-31 23:16:50 +08:00
break;
case Error::BadLevel:
err_words = u8"Your specified report level filter name is invalid.";
2026-01-31 23:16:50 +08:00
break;
default:
err_words = u8"Unknown error.";
2026-01-31 23:16:50 +08:00
break;
}
termcolor::cprintln(err_words, Color::Red);
termcolor::cprintln(u8"Please browse manual or use -h switch to see help first.", Color::Red);
2026-01-31 23:16:50 +08:00
return std::nullopt;
}
}
2026-02-02 14:17:31 +08:00
static std::optional<BMapInspector::Map::Level> LoadLevel(BMapInspector::Cli::Args& args) {
auto level = BMapInspector::Map::load(args);
if (level.has_value()) {
return std::move(level.value());
} else {
using BMapInspector::Map::Error;
std::u8string err_words;
switch (level.error()) {
case Error::BadTempDir:
err_words = u8"Can not set temporary directory for loading.";
break;
case Error::BadBallance:
err_words = u8"Can not find Ballance texture directory.";
break;
case Error::BadEncoding:
err_words = u8"Can not set encoding with your given name.";
break;
case Error::BadMap:
err_words = u8"Can not load your given map file.";
break;
default:
err_words = u8"Unknown error.";
break;
}
termcolor::cprintln(err_words, Color::Red);
termcolor::cprintln(u8"Please carefully check your map file and parameters for loading this map file.", Color::Red);
return std::nullopt;
}
}
2026-01-30 20:23:39 +08:00
2026-02-02 14:17:31 +08:00
static void CheckRules(BMapInspector::Cli::Args& args, BMapInspector::Map::Level& level) {
2026-01-30 20:23:39 +08:00
// Create reporter
BMapInspector::Reporter::Reporter reporter;
2026-01-30 20:23:39 +08:00
2026-01-30 20:40:21 +08:00
// Get rule collection
2026-02-02 14:17:31 +08:00
BMapInspector::Rule::Ruleset ruleset;
2026-01-30 20:40:21 +08:00
// Show rule infos
2026-02-02 14:17:31 +08:00
std::cout << strop::printf(u8"Total %" PRIuSIZET " rule(s) are loaded.", ruleset.GetRuleCount()) << std::endl
2026-01-31 23:16:50 +08:00
<< u8"Check may take few minutes. Please do not close this console..." << std::endl;
// Check rules one by one
2026-02-02 14:17:31 +08:00
for (auto* rule : ruleset.GetRules()) {
rule->Check(reporter, level);
}
2026-01-30 20:40:21 +08:00
// Show report conclusion
auto digest = reporter.GetDigest();
termcolor::cprintln(strop::printf(u8"Total %" PRIuSIZET " error(s), %" PRIuSIZET " warning(s) and %" PRIuSIZET " info(s).",
digest.cnt_err,
digest.cnt_warn,
digest.cnt_info),
Color::LightYellow);
2026-01-30 20:40:21 +08:00
// Print report in detail
using BMapInspector::Utils::ReportLevel;
for (const auto& report : reporter.GetReports()) {
2026-02-02 14:17:31 +08:00
// Filter report first
if (!BMapInspector::Utils::FilterReportLevel(report.level, args.level)) continue;
// Okey, output this report.
switch (report.level) {
case ReportLevel::Error:
termcolor::cprintln(strop::printf(u8"[ERROR] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::Red);
break;
case ReportLevel::Warning:
termcolor::cprintln(strop::printf(u8"[WARNING] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::Yellow);
break;
case ReportLevel::Info:
termcolor::cprintln(strop::printf(u8"[INFO] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::White);
break;
}
}
2026-01-31 23:16:50 +08:00
}
int main(int argc, char* argv[]) {
2026-01-31 23:16:50 +08:00
auto args = AcceptArgs();
if (args.has_value()) {
PrintSplash();
std::cout << std::endl;
2026-01-30 20:23:39 +08:00
2026-02-02 14:17:31 +08:00
auto level = LoadLevel(args.value());
if (level.has_value()) {
CheckRules(args.value(), level.value());
}
2026-01-31 23:16:50 +08:00
}
return 0;
}