From 627df3644730da2bebe449c8ec68f0bce8112683 Mon Sep 17 00:00:00 2001 From: MistEO Date: Mon, 14 Aug 2023 15:21:00 +0800 Subject: [PATCH] feat: merge and re-structure stage.json fix #5881 --- tools/ResourceUpdater/main.cpp | 75 ++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/tools/ResourceUpdater/main.cpp b/tools/ResourceUpdater/main.cpp index 1b299be689..d489ab3bc9 100644 --- a/tools/ResourceUpdater/main.cpp +++ b/tools/ResourceUpdater/main.cpp @@ -505,24 +505,75 @@ bool update_infrast_data(const std::filesystem::path& input_dir, const std::file bool update_stages_data(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir) { // 国内访问可以改成 .cn 的域名 - const std::string PenguinAPI = R"(https://penguin-stats.io/PenguinStats/api/v2/stages)"; + const std::string PenguinAPI = R"(https://penguin-stats.io/PenguinStats/api/v2/stages?server=)"; + const std::vector PenguinServers = { "CN", "US", "JP", "KR" }; + const std::filesystem::path TempFile = input_dir / "stages.json"; - int stage_request_ret = system(("curl -o \"" + TempFile.string() + "\" " + PenguinAPI).c_str()); - if (stage_request_ret != 0) { - std::cerr << "Request Penguin Stats failed" << std::endl; - return false; + + struct DropInfo + { + std::string item_id; + std::string drop_type; + bool operator<(const DropInfo& rhs) const { return item_id + drop_type < rhs.item_id + drop_type; } + bool operator==(const DropInfo& rhs) const { return item_id == rhs.item_id && drop_type == rhs.drop_type; } + }; + + std::map> drop_infos; + std::map stage_basic_infos; + for (const auto& server : PenguinServers) { + int stage_request_ret = system(("curl -o \"" + TempFile.string() + "\" " + PenguinAPI + server).c_str()); + if (stage_request_ret != 0) { + std::cerr << "Request Penguin Stats failed" << std::endl; + return false; + } + + auto parse_ret = json::open(TempFile); + if (!parse_ret) { + std::cerr << "parse stages.json failed" << std::endl; + return false; + } + auto& stage_json = parse_ret.value(); + + for (auto& stage : stage_json.as_array()) { + if (!stage.contains("dropInfos")) { + continue; + } + std::string stage_id = stage.at("stageId").as_string(); + for (auto& drop_json : stage["dropInfos"].as_array()) { + DropInfo drop; + drop.item_id = drop_json.get("itemId", std::string()); + if (drop.item_id.empty()) { + continue; + } + + drop.drop_type = drop_json.at("dropType").as_string(); + drop_infos[stage_id].emplace(std::move(drop)); + } + + json::value basic_json; + basic_json["apCost"] = stage["apCost"]; + basic_json["code"] = stage["code"]; + basic_json["stageId"] = stage["stageId"]; + stage_basic_infos.emplace(stage_id, std::move(basic_json)); + } } - auto parse_ret = json::open(TempFile); - if (!parse_ret) { - std::cerr << "parse stages.json failed" << std::endl; - return false; + json::array result; + for (const auto& [stage_id, drops] : drop_infos) { + json::array drops_json; + for (const auto& d : drops) { + drops_json.emplace_back(json::object { + { "itemId", d.item_id }, + { "dropType", d.drop_type }, + }); + } + auto& stage = stage_basic_infos.at(stage_id); + stage["dropInfos"] = std::move(drops_json); + result.emplace_back(std::move(stage)); } - auto& stage_json = parse_ret.value(); - std::ofstream ofs(output_dir / "stages.json", std::ios::out); - ofs << stage_json.format(); + ofs << result.format(); ofs.close(); return true;