From f4bfa619c8b2464970929d9553e599df9677eeaa Mon Sep 17 00:00:00 2001 From: zzyyyl Date: Fri, 22 Jul 2022 15:25:45 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E6=8A=8A=E8=82=89=E9=B8=BD=E6=8B=9B?= =?UTF-8?q?=E5=8B=9F=E6=95=B0=E6=8D=AE=E7=9A=84=E7=94=9F=E6=88=90=E9=9B=86?= =?UTF-8?q?=E6=88=90=E5=88=B0=20ResourceUpdater=20=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/ResourceUpdater/ResourceUpdater.vcxproj | 2 +- tools/ResourceUpdater/main.cpp | 161 ++++++++++++++++++ .../generate_roguelike_recruit.py | 25 ++- 3 files changed, 180 insertions(+), 8 deletions(-) diff --git a/tools/ResourceUpdater/ResourceUpdater.vcxproj b/tools/ResourceUpdater/ResourceUpdater.vcxproj index 4796d3c0ea..b583a413c8 100644 --- a/tools/ResourceUpdater/ResourceUpdater.vcxproj +++ b/tools/ResourceUpdater/ResourceUpdater.vcxproj @@ -32,7 +32,7 @@ false - $(SolutionDir)3rdparty\include;$(VC_IncludePath);$(WindowsSDK_IncludePath) + $(SolutionDir)3rdparty\include;$(SolutionDir)src\MeoAssistant;$(VC_IncludePath);$(WindowsSDK_IncludePath) $(SolutionDir)3rdparty\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64) diff --git a/tools/ResourceUpdater/main.cpp b/tools/ResourceUpdater/main.cpp index ef13161bcb..f207f712a1 100644 --- a/tools/ResourceUpdater/main.cpp +++ b/tools/ResourceUpdater/main.cpp @@ -4,12 +4,14 @@ #include #include +#include bool update_items_data(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); bool cvt_single_item_template(const std::filesystem::path& input, const std::filesystem::path& output); bool update_infrast_data(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); bool update_stages_data(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); +bool update_roguelike_recruit(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); bool update_infrast_templates(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir); bool generate_english_roguelike_stage_name_replacement(const std::filesystem::path& ch_file, const std::filesystem::path& en_file); @@ -72,6 +74,13 @@ int main([[maybe_unused]] int argc, char** argv) return -1; } + /* Update roguelike recruit data from Arknights-Bot-Resource*/ + std::cout << "------------Update roguelike recruit data------------" << std::endl; + if (!update_roguelike_recruit(input_dir, resource_dir)) { + std::cerr << "Update roguelike recruit data failed" << std::endl; + return -1; + } + /* Update stage.json from Penguin Stats*/ std::cout << "------------Update stage.json------------" << std::endl; if (!update_stages_data(cur_path, solution_dir / "resource")) { @@ -421,6 +430,158 @@ bool update_infrast_templates(const std::filesystem::path& input_dir, const std: return true; } +bool update_roguelike_recruit(const std::filesystem::path& input_dir, const std::filesystem::path& output_dir) +{ + std::string python_cmd; + const auto solution_dir = std::filesystem::current_path().parent_path().parent_path(); + std::filesystem::path python_file = solution_dir / "tools" / "RoguelikeResourceUpdater" / "generate_roguelike_recruit.py"; + python_cmd = "python " + python_file.string() + " --input=\"" + input_dir.string() + "\" --output=\"" + output_dir.string() + "\""; + std::cout << python_cmd << std::endl; + int python_ret = system(python_cmd.c_str()); + if (python_ret != 0) { + return false; + } + return true; +/* + const auto input_file = input_dir / "gamedata" / "excel" / "character_table.json"; + const auto output_file = output_dir / "roguelike_recruit.json"; + + json::value input_json; + { + auto opt = json::open(input_file); + if (!opt) { + std::cout << input_file << " parse error" << std::endl; + return false; + } + input_json = std::move(opt.value()); + } + + json::value old_json; + { + auto opt = json::open(output_file); + if (!opt) { + std::cout << output_file << " parse error" << std::endl; + return false; + } + old_json = std::move(opt.value()); + } + for (auto& [x, y] : old_json.as_object()) { + std::cout << x << std::endl; + } + std::unordered_map name_replace_map = {}; + const std::unordered_map default_position = { + { "Warrior", "MELEE" }, + { "Pioneer", "MELEE" }, + { "Caster", "RANGED" }, + { "Sniper", "RANGED" }, + { "Medic", "RANGED" }, + { "Special", "MELEE" }, + { "Tank", "MELEE" }, + { "Support", "RANGED" } + }; + json::value old_employee_data; + + for (const std::string& profession : + { "Warrior", "Pioneer", "Caster", "Sniper", "Medic", "Special", "Tank", "Support" }) { + for (auto& item : old_json[profession].as_array()) { + auto name = item["name"].as_string(); + if (name.find("_N") != std::string::npos) { + name_replace_map[name] = asst::utils::string_replace_all(name, "_N", ""); + old_employee_data[profession][name_replace_map[name]] = item; + } + else { + old_employee_data[profession][name] = item; + } + } + } + + json::value new_json = old_json; + for (auto& [x, y] : input_json.as_object()) { + static auto profession_filter = [](const std::string& profession) -> bool { + for (auto& x : { "WARRIOR", "PIONEER", "CASTER", "SNIPER", + "MEDIC", "SPECIAL", "TANK", "SUPPORT" }) { + if (profession == x) return true; + } + return false; + }; + static auto title = [](const std::string& str) -> std::string { + std::string s = str; + std::for_each(s.begin(), s.end(), [](char& c) { c = char(std::tolower(c)); }); + if (!s.empty()) { + s[0] = char(std::toupper(s[0])); + } + return s; + }; + if (!profession_filter(y["profession"].as_string())) { + continue; + } + if (y["name"].as_string().find("预备干员") != std::string::npos) { + continue; + } + auto profession = title(y["profession"].as_string()); + json::value employee_info; + employee_info["name"] = y["name"]; + employee_info["level"] = y["rarity"].as_integer() + 1; + + // 和默认位置不同,直接禁用 + if (auto iter = default_position.find(profession); + iter != default_position.end() && + iter->second != y["position"].as_string()) { + employee_info["name"] = employee_info["name"].as_string() + "_N"; + } + + // 四星以上的干员设二技能 + if (employee_info["level"].as_integer() >= 4) { + employee_info["skill"] = 2; + } + // 三星的干员设一技能 + else if (employee_info["level"].as_integer() == 3) { + employee_info["skill"] = 1; + } + // 二星以下的干员不设技能 + else { + employee_info["skill"] = 0; + } + + if (old_employee_data[profession].as_object().contains(y["name"].as_string())) { + auto old_employee_info = old_employee_data[profession][y["name"].as_string()]; + employee_info["skill"] = + old_employee_info.get("skill", employee_info["skill"].as_integer()); + if (employee_info.contains("alternate_skill")) + employee_info["alternate_skill"] = old_employee_info.get("alternate_skill", 0); + if (employee_info.contains("skill_usage")) + employee_info["skill_usage"] = old_employee_info.get("skill_usage", 0); + for (auto& employee : new_json[profession].as_array()) { + if (employee["name"].as_string() == y["name"].as_string()) { + for (auto& [key, val] : employee_info.as_object()) { + employee[key] = val; + } + break; + } + else if (auto iter = name_replace_map.find(employee["name"].as_string()); + iter != name_replace_map.end() && + iter->second == y["name"].as_string()) { + employee_info["name"] = employee["name"]; + for (auto& [key, val] : employee_info.as_object()) { + employee[key] = val; + } + break; + } + } + } + else { + new_json[profession].array_emplace(employee_info); + } + } + + std::ofstream ofs(output_file, std::ios::out); + ofs << new_json.format(); + ofs.close(); + + return true; +*/ +} + bool generate_english_roguelike_stage_name_replacement(const std::filesystem::path& ch_file, const std::filesystem::path& en_file) { auto ch_opt = json::open(ch_file); diff --git a/tools/RoguelikeResourceUpdater/generate_roguelike_recruit.py b/tools/RoguelikeResourceUpdater/generate_roguelike_recruit.py index 22633e7cdc..f2e393a2f0 100644 --- a/tools/RoguelikeResourceUpdater/generate_roguelike_recruit.py +++ b/tools/RoguelikeResourceUpdater/generate_roguelike_recruit.py @@ -1,13 +1,24 @@ +from argparse import ArgumentParser import json import requests +import os -url = "https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/character_table.json" -# 记得改下面的 proxies!!! -res = requests.get(url, proxies = {"https": "http://127.0.0.1:1080"}) -raw_employee_infos = json.loads(res.text) +def ArgParser(): + parser = ArgumentParser() + parser.add_argument("--input", help="input dir", metavar="I", dest="src", required=True) + parser.add_argument("--output", help="output dir", metavar="O", dest="det", required=True) + return parser -# 记得改下面的路径!!! -with open("../../resource/roguelike_recruit.json", "r", encoding="utf8") as f: +args = ArgParser().parse_args() + +input_dir = args.src +output_dir = args.det +input_file = os.path.join(input_dir, "gamedata/excel/character_table.json") +output_file = os.path.join(output_dir, "roguelike_recruit.json") + +with open(input_file, "r", encoding="utf8") as f: + raw_employee_infos = json.load(f) +with open(output_file, "r", encoding="utf8") as f: old_res = json.load(f) old_dic = { @@ -103,5 +114,5 @@ for x, y in raw_employee_infos.items(): dump_cache = json.dumps(res, ensure_ascii=False, indent=4).encode("utf8").replace(b"\r\n", b"\n") # 记得改下面的路径!!! -with open("../../resource/roguelike_recruit.json", "wb") as f: +with open(output_file, "wb") as f: f.write(dump_cache)