2024-12-20 02:03:16 +00:00
|
|
|
#include <sqlite3.h>
|
2024-10-17 23:11:34 +00:00
|
|
|
#include "infra/infra.h"
|
|
|
|
#include "jobs.hpp"
|
2024-11-25 21:17:20 +00:00
|
|
|
#include "utils/cli.h"
|
2024-10-17 00:50:14 +00:00
|
|
|
|
|
|
|
using Infra::kgm_ekey_db_t;
|
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
void WalkFileOrDir(KggTaskQueue& queue, const std::filesystem::path& input_path, bool scan_all_exts) {
|
|
|
|
std::queue<std::filesystem::path> file_queue;
|
|
|
|
file_queue.push(absolute(input_path));
|
2024-10-17 00:50:14 +00:00
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
while (!file_queue.empty()) {
|
|
|
|
auto target_path = std::move(file_queue.front());
|
|
|
|
file_queue.pop();
|
2024-10-17 00:50:14 +00:00
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
if (is_regular_file(target_path)) {
|
|
|
|
if (!scan_all_exts && target_path.extension() != L".kgg") {
|
|
|
|
continue;
|
|
|
|
}
|
2024-10-17 00:50:14 +00:00
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
queue.Push(std::make_unique<KggTask>(target_path, target_path.parent_path()));
|
|
|
|
continue;
|
|
|
|
}
|
2024-10-17 00:50:14 +00:00
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
if (is_directory(target_path)) {
|
|
|
|
for (auto const& dir_entry : std::filesystem::directory_iterator{target_path}) {
|
|
|
|
file_queue.push(dir_entry.path());
|
|
|
|
}
|
|
|
|
continue;
|
2024-10-17 00:50:14 +00:00
|
|
|
}
|
2024-10-17 23:11:34 +00:00
|
|
|
|
|
|
|
fwprintf(stderr, L"[WARN] invalid path: %s\n", target_path.c_str());
|
2024-10-17 20:35:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
void print_license() {
|
|
|
|
fputs(" This software is free and open source, licensed under the MIT license.\n", stderr);
|
|
|
|
fputs(" For more details, check out: https://git.unlock-music.dev/um/kgg-dec\n", stderr);
|
2024-10-17 00:50:14 +00:00
|
|
|
}
|
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
void print_usage() {
|
2024-10-17 20:35:17 +00:00
|
|
|
fputs(
|
|
|
|
"Usage: kgg-dec "
|
2024-10-17 23:11:34 +00:00
|
|
|
"[--scan-all-file-ext 0] "
|
2024-10-17 20:35:17 +00:00
|
|
|
"[--db /path/to/KGMusicV3.db] "
|
2024-11-25 21:17:20 +00:00
|
|
|
"[--suffix _kgg-dec] "
|
|
|
|
"[--] "
|
|
|
|
"[FILE]...\n\n\n",
|
2024-10-17 20:35:17 +00:00
|
|
|
stderr);
|
2024-11-25 21:17:20 +00:00
|
|
|
}
|
2024-10-17 20:35:17 +00:00
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
void print_banner() {
|
|
|
|
fprintf(stderr, "kgg-dec v" KGGDEC_PROJECT_VERSION " by LSR\n");
|
|
|
|
print_license();
|
|
|
|
print_usage();
|
|
|
|
}
|
2024-10-17 20:35:17 +00:00
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
int main() {
|
|
|
|
CliParser cli_args;
|
|
|
|
print_banner();
|
2024-10-17 20:35:17 +00:00
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
cli_args.parse_from_cli();
|
2024-10-17 23:11:34 +00:00
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
bool scan_all_exts = cli_args.get_scan_all_file_ext();
|
|
|
|
|
|
|
|
auto kgm_db_path = cli_args.get_db_path();
|
|
|
|
auto file_suffix = cli_args.get_file_suffix();
|
|
|
|
{
|
|
|
|
bool cli_arg_error{false};
|
|
|
|
|
|
|
|
if (!exists(kgm_db_path)) {
|
|
|
|
fputs("[ERR ] KGMusicV3.db not found\n", stderr);
|
|
|
|
cli_arg_error = true;
|
|
|
|
}
|
|
|
|
if (cli_arg_error) {
|
|
|
|
return 1;
|
|
|
|
}
|
2024-10-17 20:35:17 +00:00
|
|
|
}
|
2024-10-17 00:50:14 +00:00
|
|
|
|
2024-12-20 02:03:16 +00:00
|
|
|
kgm_ekey_db_t ekey_db;
|
|
|
|
if (const auto rc = Infra::dump_ekey(ekey_db, kgm_db_path); rc != 0) {
|
|
|
|
fprintf(stderr, "[ERR ] dump ekey failed %d (%s)", rc, sqlite3_errstr(rc));
|
2024-10-17 00:50:14 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-10-17 23:11:34 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
fprintf(stderr, "ekey_db:\n");
|
2024-10-17 00:50:14 +00:00
|
|
|
for (auto& [a, b] : ekey_db) {
|
2024-10-17 23:11:34 +00:00
|
|
|
fprintf(stderr, "%s --> %s\n", a.c_str(), b.c_str());
|
2024-10-17 00:50:14 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2024-11-25 21:51:21 +00:00
|
|
|
KggTaskQueue queue(ekey_db, file_suffix);
|
2024-10-17 23:11:34 +00:00
|
|
|
auto thread_count =
|
|
|
|
#ifndef NDEBUG
|
|
|
|
1;
|
|
|
|
#else
|
|
|
|
std::max(static_cast<int>(std::thread::hardware_concurrency()) - 2, 2);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
for (int i = 0; i < thread_count; i++) {
|
|
|
|
queue.AddWorkerThread();
|
|
|
|
}
|
|
|
|
|
2024-11-25 21:17:20 +00:00
|
|
|
auto input_files = cli_args.get_input_files();
|
|
|
|
if (input_files.empty()) {
|
|
|
|
input_files.emplace_back(L".");
|
|
|
|
}
|
|
|
|
for (auto& positional_arg : input_files) {
|
2024-10-17 23:11:34 +00:00
|
|
|
WalkFileOrDir(queue, positional_arg, scan_all_exts);
|
2024-10-17 20:35:17 +00:00
|
|
|
}
|
2024-10-17 23:11:34 +00:00
|
|
|
queue.Join();
|
2024-10-17 00:50:14 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|