mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
重构Configer
This commit is contained in:
43
MeoAssistance/AbstractConfiger.cpp
Normal file
43
MeoAssistance/AbstractConfiger.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "AbstractConfiger.h"
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
#include <json.h>
|
||||
|
||||
#include "Logger.hpp"
|
||||
|
||||
bool asst::AbstractConfiger::load(const std::string& filename)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Configer::load | ", filename);
|
||||
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return false;
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::string content(iss.str());
|
||||
|
||||
auto&& ret = json::parser::parse(content);
|
||||
if (!ret) {
|
||||
DebugTrace("parse error", content);
|
||||
return false;
|
||||
}
|
||||
|
||||
json::value root = std::move(ret.value());
|
||||
|
||||
try {
|
||||
parse(std::move(root));
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
DebugTraceError("Load config json error!", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugTrace("Load config succeed");
|
||||
return true;
|
||||
}
|
||||
31
MeoAssistance/AbstractConfiger.h
Normal file
31
MeoAssistance/AbstractConfiger.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace json {
|
||||
class value;
|
||||
}
|
||||
|
||||
namespace asst {
|
||||
class AbstractConfiger
|
||||
{
|
||||
public:
|
||||
virtual ~AbstractConfiger() = default;
|
||||
virtual bool load(const std::string& filename);
|
||||
|
||||
protected:
|
||||
AbstractConfiger() = default;
|
||||
AbstractConfiger(const AbstractConfiger& rhs) = default;
|
||||
AbstractConfiger(AbstractConfiger&& rhs) noexcept = default;
|
||||
|
||||
AbstractConfiger& operator=(const AbstractConfiger& rhs) = default;
|
||||
AbstractConfiger& operator=(AbstractConfiger&& rhs) noexcept = default;
|
||||
|
||||
virtual bool parse(json::value&& json) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,37 +10,6 @@
|
||||
|
||||
using namespace asst;
|
||||
|
||||
//Configer::Configer(const Configer& rhs)
|
||||
// : m_version(rhs.m_version),
|
||||
// m_options(rhs.m_options),
|
||||
// m_tasks(rhs.m_tasks),
|
||||
// m_handles(rhs.m_handles)
|
||||
//{
|
||||
//}
|
||||
//
|
||||
//Configer::Configer(Configer&& rhs) noexcept
|
||||
// : m_version(std::move(rhs.m_version)),
|
||||
// m_options(std::move(rhs.m_options)),
|
||||
// m_tasks(std::move(rhs.m_tasks)),
|
||||
// m_handles(std::move(rhs.m_handles))
|
||||
//{
|
||||
//}
|
||||
|
||||
bool Configer::load(const std::string& filename)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Configer::load | ", filename);
|
||||
|
||||
Configer temp;
|
||||
if (temp._load(filename)) {
|
||||
*this = std::move(temp);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Configer::set_param(const std::string& type, const std::string& param, const std::string& value)
|
||||
{
|
||||
// 暂时只用到了这些,总的参数太多了,后面要用啥再加上
|
||||
@@ -80,209 +49,188 @@ bool Configer::set_param(const std::string& type, const std::string& param, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asst::Configer::_load(const std::string& filename)
|
||||
bool asst::Configer::parse(json::value&& json)
|
||||
{
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return false;
|
||||
json::value root = std::move(json);
|
||||
|
||||
m_version = root["version"].as_string();
|
||||
|
||||
json::value& options_json = root["options"];
|
||||
{
|
||||
m_options.task_identify_delay = options_json["taskIdentifyDelay"].as_integer();
|
||||
m_options.task_control_delay = options_json["taskControlDelay"].as_integer();
|
||||
m_options.identify_cache = options_json["identifyCache"].as_boolean();
|
||||
m_options.control_delay_lower = options_json["controlDelayRange"][0].as_integer();
|
||||
m_options.control_delay_upper = options_json["controlDelayRange"][1].as_integer();
|
||||
m_options.print_window = options_json["printWindow"].as_boolean();
|
||||
m_options.print_window_delay = options_json["printWindowDelay"].as_integer();
|
||||
m_options.print_window_crop_offset = options_json["printWindowCropOffset"].as_integer();
|
||||
m_options.ocr_gpu_index = options_json["ocrGpuIndex"].as_integer();
|
||||
m_options.ocr_thread_number = options_json["ocrThreadNumber"].as_integer();
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::string content(iss.str());
|
||||
DebugTrace("Options", Utf8ToGbk(options_json.to_string()));
|
||||
|
||||
auto&& ret = json::parser::parse(content);
|
||||
if (!ret) {
|
||||
DebugTrace("parse error", content);
|
||||
return false;
|
||||
}
|
||||
for (auto&& [name, task_json] : root["tasks"].as_object()) {
|
||||
std::string algorithm_str = task_json.get("algorithm", "matchtemplate");
|
||||
std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), std::tolower);
|
||||
AlgorithmType algorithm = AlgorithmType::Invaild;
|
||||
if (algorithm_str == "matchtemplate") {
|
||||
algorithm = AlgorithmType::MatchTemplate;
|
||||
}
|
||||
else if (algorithm_str == "justreturn") {
|
||||
algorithm = AlgorithmType::JustReturn;
|
||||
}
|
||||
else if (algorithm_str == "ocrdetect") {
|
||||
algorithm = AlgorithmType::OcrDetect;
|
||||
}
|
||||
//else if (algorithm_str == "comparehist") {} // CompareHist是MatchTemplate的衍生算法,不应作为单独的配置参数出现
|
||||
else {
|
||||
DebugTraceError("Algorithm error:", algorithm_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
json::value root = ret.value();
|
||||
try {
|
||||
m_version = root["version"].as_string();
|
||||
|
||||
json::value& options_json = root["options"];
|
||||
std::shared_ptr<TaskInfo> task_info_ptr = nullptr;
|
||||
switch (algorithm) {
|
||||
case AlgorithmType::JustReturn:
|
||||
task_info_ptr = std::make_shared<TaskInfo>();
|
||||
break;
|
||||
case AlgorithmType::MatchTemplate:
|
||||
{
|
||||
m_options.task_identify_delay = options_json["taskIdentifyDelay"].as_integer();
|
||||
m_options.task_control_delay = options_json["taskControlDelay"].as_integer();
|
||||
m_options.identify_cache = options_json["identifyCache"].as_boolean();
|
||||
m_options.control_delay_lower = options_json["controlDelayRange"][0].as_integer();
|
||||
m_options.control_delay_upper = options_json["controlDelayRange"][1].as_integer();
|
||||
m_options.print_window = options_json["printWindow"].as_boolean();
|
||||
m_options.print_window_delay = options_json["printWindowDelay"].as_integer();
|
||||
m_options.print_window_crop_offset = options_json["printWindowCropOffset"].as_integer();
|
||||
m_options.ocr_gpu_index = options_json["ocrGpuIndex"].as_integer();
|
||||
m_options.ocr_thread_number = options_json["ocrThreadNumber"].as_integer();
|
||||
auto match_task_info_ptr = std::make_shared<MatchTaskInfo>();
|
||||
match_task_info_ptr->template_filename = task_json["template"].as_string();
|
||||
match_task_info_ptr->templ_threshold = task_json.get("templThreshold", Defaulttempl_threshold);
|
||||
match_task_info_ptr->hist_threshold = task_json.get("histThreshold", DefaultCachetempl_threshold);
|
||||
task_info_ptr = match_task_info_ptr;
|
||||
}
|
||||
DebugTrace("Options", Utf8ToGbk(options_json.to_string()));
|
||||
|
||||
for (auto&& [name, task_json] : root["tasks"].as_object()) {
|
||||
std::string algorithm_str = task_json.get("algorithm", "matchtemplate");
|
||||
std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), std::tolower);
|
||||
AlgorithmType algorithm = AlgorithmType::Invaild;
|
||||
if (algorithm_str == "matchtemplate") {
|
||||
algorithm = AlgorithmType::MatchTemplate;
|
||||
}
|
||||
else if (algorithm_str == "justreturn") {
|
||||
algorithm = AlgorithmType::JustReturn;
|
||||
}
|
||||
else if (algorithm_str == "ocrdetect") {
|
||||
algorithm = AlgorithmType::OcrDetect;
|
||||
}
|
||||
//else if (algorithm_str == "comparehist") {} // CompareHist是MatchTemplate的衍生算法,不应作为单独的配置参数出现
|
||||
else {
|
||||
DebugTraceError("Algorithm error:", algorithm_str);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<TaskInfo> task_info_ptr = nullptr;
|
||||
switch (algorithm) {
|
||||
case AlgorithmType::JustReturn:
|
||||
task_info_ptr = std::make_shared<TaskInfo>();
|
||||
break;
|
||||
case AlgorithmType::MatchTemplate:
|
||||
break;
|
||||
case AlgorithmType::OcrDetect:
|
||||
{
|
||||
auto ocr_task_info_ptr = std::make_shared<OcrTaskInfo>();
|
||||
for (const json::value& text : task_json["text"].as_array())
|
||||
{
|
||||
auto match_task_info_ptr = std::make_shared<MatchTaskInfo>();
|
||||
match_task_info_ptr->template_filename = task_json["template"].as_string();
|
||||
match_task_info_ptr->templ_threshold = task_json.get("templThreshold", Defaulttempl_threshold);
|
||||
match_task_info_ptr->hist_threshold = task_json.get("histThreshold", DefaultCachetempl_threshold);
|
||||
task_info_ptr = match_task_info_ptr;
|
||||
ocr_task_info_ptr->text.emplace_back(text.as_string());
|
||||
}
|
||||
break;
|
||||
case AlgorithmType::OcrDetect:
|
||||
ocr_task_info_ptr->need_match = task_json.get("need_match", false);
|
||||
if (task_json.exist("ocrReplace"))
|
||||
{
|
||||
auto ocr_task_info_ptr = std::make_shared<OcrTaskInfo>();
|
||||
for (const json::value& text : task_json["text"].as_array())
|
||||
{
|
||||
ocr_task_info_ptr->text.emplace_back(text.as_string());
|
||||
}
|
||||
ocr_task_info_ptr->need_match = task_json.get("need_match", false);
|
||||
if (task_json.exist("ocrReplace"))
|
||||
{
|
||||
for (const auto& [key, value] : task_json["ocrReplace"].as_object()) {
|
||||
ocr_task_info_ptr->replace_map.emplace(key, value.as_string());
|
||||
}
|
||||
}
|
||||
task_info_ptr = ocr_task_info_ptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
task_info_ptr->algorithm = algorithm;
|
||||
task_info_ptr->name = name;
|
||||
std::string type = task_json["type"].as_string();
|
||||
std::transform(type.begin(), type.end(), type.begin(), std::tolower);
|
||||
if (type == "clickself") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickSelf;
|
||||
}
|
||||
else if (type == "clickrand") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickRand;
|
||||
}
|
||||
else if (type == "donothing" || type.empty()) {
|
||||
task_info_ptr->type = ProcessTaskType::DoNothing;
|
||||
}
|
||||
else if (type == "stop") {
|
||||
task_info_ptr->type = ProcessTaskType::Stop;
|
||||
}
|
||||
else if (type == "clickrect") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickRect;
|
||||
json::value& area_json = task_json["specificArea"];
|
||||
task_info_ptr->specific_area = Rect(
|
||||
area_json[0].as_integer(),
|
||||
area_json[1].as_integer(),
|
||||
area_json[2].as_integer(),
|
||||
area_json[3].as_integer());
|
||||
}
|
||||
else if (type == "printwindow") {
|
||||
task_info_ptr->type = ProcessTaskType::PrintWindow;
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Task:", name, "error:", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
task_info_ptr->max_times = task_json.get("maxTimes", INT_MAX);
|
||||
if (task_json.exist("exceededNext")) {
|
||||
json::array& excceed_next_arr = task_json["exceededNext"].as_array();
|
||||
for (const json::value& excceed_next : excceed_next_arr) {
|
||||
task_info_ptr->exceeded_next.emplace_back(excceed_next.as_string());
|
||||
for (const auto& [key, value] : task_json["ocrReplace"].as_object()) {
|
||||
ocr_task_info_ptr->replace_map.emplace(key, value.as_string());
|
||||
}
|
||||
}
|
||||
else {
|
||||
task_info_ptr->exceeded_next.emplace_back("Stop");
|
||||
}
|
||||
task_info_ptr->pre_delay = task_json.get("preDelay", 0);
|
||||
task_info_ptr->rear_delay = task_json.get("rearDelay", 0);
|
||||
if (task_json.exist("reduceOtherTimes")) {
|
||||
json::array& reduce_arr = task_json["reduceOtherTimes"].as_array();
|
||||
for (const json::value& reduce : reduce_arr) {
|
||||
task_info_ptr->reduce_other_times.emplace_back(reduce.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
json::array& next_arr = task_json["next"].as_array();
|
||||
for (const json::value& next : next_arr) {
|
||||
task_info_ptr->next.emplace_back(next.as_string());
|
||||
}
|
||||
|
||||
m_all_tasks_info.emplace(name, task_info_ptr);
|
||||
task_info_ptr = ocr_task_info_ptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
task_info_ptr->algorithm = algorithm;
|
||||
task_info_ptr->name = name;
|
||||
std::string type = task_json["type"].as_string();
|
||||
std::transform(type.begin(), type.end(), type.begin(), std::tolower);
|
||||
if (type == "clickself") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickSelf;
|
||||
}
|
||||
else if (type == "clickrand") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickRand;
|
||||
}
|
||||
else if (type == "donothing" || type.empty()) {
|
||||
task_info_ptr->type = ProcessTaskType::DoNothing;
|
||||
}
|
||||
else if (type == "stop") {
|
||||
task_info_ptr->type = ProcessTaskType::Stop;
|
||||
}
|
||||
else if (type == "clickrect") {
|
||||
task_info_ptr->type = ProcessTaskType::ClickRect;
|
||||
json::value& area_json = task_json["specificArea"];
|
||||
task_info_ptr->specific_area = Rect(
|
||||
area_json[0].as_integer(),
|
||||
area_json[1].as_integer(),
|
||||
area_json[2].as_integer(),
|
||||
area_json[3].as_integer());
|
||||
}
|
||||
else if (type == "printwindow") {
|
||||
task_info_ptr->type = ProcessTaskType::PrintWindow;
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Task:", name, "error:", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto&& [name, emulator_json] : root["handle"].as_object()) {
|
||||
EmulatorInfo emulator_info;
|
||||
emulator_info.name = name;
|
||||
|
||||
for (json::value& info : emulator_json["window"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.window.emplace_back(std::move(handle_info));
|
||||
task_info_ptr->max_times = task_json.get("maxTimes", INT_MAX);
|
||||
if (task_json.exist("exceededNext")) {
|
||||
json::array& excceed_next_arr = task_json["exceededNext"].as_array();
|
||||
for (const json::value& excceed_next : excceed_next_arr) {
|
||||
task_info_ptr->exceeded_next.emplace_back(excceed_next.as_string());
|
||||
}
|
||||
for (json::value& info : emulator_json["view"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.view.emplace_back(std::move(handle_info));
|
||||
}
|
||||
else {
|
||||
task_info_ptr->exceeded_next.emplace_back("Stop");
|
||||
}
|
||||
task_info_ptr->pre_delay = task_json.get("preDelay", 0);
|
||||
task_info_ptr->rear_delay = task_json.get("rearDelay", 0);
|
||||
if (task_json.exist("reduceOtherTimes")) {
|
||||
json::array& reduce_arr = task_json["reduceOtherTimes"].as_array();
|
||||
for (const json::value& reduce : reduce_arr) {
|
||||
task_info_ptr->reduce_other_times.emplace_back(reduce.as_string());
|
||||
}
|
||||
for (json::value& info : emulator_json["control"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.control.emplace_back(std::move(handle_info));
|
||||
}
|
||||
if (emulator_json.exist("adb")) {
|
||||
emulator_info.is_adb = true;
|
||||
emulator_info.adb.path = emulator_json["adb"]["path"].as_string();
|
||||
emulator_info.adb.connect = emulator_json["adb"]["connect"].as_string();
|
||||
emulator_info.adb.click = emulator_json["adb"]["click"].as_string();
|
||||
emulator_info.adb.swipe = emulator_json["adb"]["swipe"].as_string();
|
||||
emulator_info.adb.display = emulator_json["adb"]["display"].as_string();
|
||||
emulator_info.adb.display_regex = emulator_json["adb"]["displayRegex"].as_string();
|
||||
emulator_info.adb.screencap = emulator_json["adb"]["screencap"].as_string();
|
||||
emulator_info.adb.pullscreen = emulator_json["adb"]["pullscreen"].as_string();
|
||||
}
|
||||
emulator_info.x_offset = emulator_json.get("xOffset", 0);
|
||||
emulator_info.y_offset = emulator_json.get("yOffset", 0);
|
||||
emulator_info.right_offset = emulator_json.get("rightOffset", 0);
|
||||
emulator_info.bottom_offset = emulator_json.get("bottomOffset", 0);
|
||||
|
||||
emulator_info.width = DefaultWindowWidth + emulator_info.x_offset + emulator_info.right_offset;
|
||||
emulator_info.height = DefaultWindowHeight + emulator_info.y_offset + emulator_info.bottom_offset;
|
||||
|
||||
m_handles.emplace(name, std::move(emulator_info));
|
||||
}
|
||||
|
||||
for (json::value& rep : root["infrastOcrReplace"].as_array()) {
|
||||
m_infrast_ocr_replace.emplace(rep.as_array()[0].as_string(), rep.as_array()[1].as_string());
|
||||
}
|
||||
for (json::value& rep : root["recruitOcrReplace"].as_array()) {
|
||||
m_recruit_ocr_replace.emplace(rep.as_array()[0].as_string(), rep.as_array()[1].as_string());
|
||||
json::array& next_arr = task_json["next"].as_array();
|
||||
for (const json::value& next : next_arr) {
|
||||
task_info_ptr->next.emplace_back(next.as_string());
|
||||
}
|
||||
|
||||
m_all_tasks_info.emplace(name, task_info_ptr);
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
DebugTraceError("Load config json error!", e.what());
|
||||
return false;
|
||||
|
||||
for (auto&& [name, emulator_json] : root["handle"].as_object()) {
|
||||
EmulatorInfo emulator_info;
|
||||
emulator_info.name = name;
|
||||
|
||||
for (json::value& info : emulator_json["window"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.window.emplace_back(std::move(handle_info));
|
||||
}
|
||||
for (json::value& info : emulator_json["view"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.view.emplace_back(std::move(handle_info));
|
||||
}
|
||||
for (json::value& info : emulator_json["control"].as_array()) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.control.emplace_back(std::move(handle_info));
|
||||
}
|
||||
if (emulator_json.exist("adb")) {
|
||||
emulator_info.is_adb = true;
|
||||
emulator_info.adb.path = emulator_json["adb"]["path"].as_string();
|
||||
emulator_info.adb.connect = emulator_json["adb"]["connect"].as_string();
|
||||
emulator_info.adb.click = emulator_json["adb"]["click"].as_string();
|
||||
emulator_info.adb.swipe = emulator_json["adb"]["swipe"].as_string();
|
||||
emulator_info.adb.display = emulator_json["adb"]["display"].as_string();
|
||||
emulator_info.adb.display_regex = emulator_json["adb"]["displayRegex"].as_string();
|
||||
emulator_info.adb.screencap = emulator_json["adb"]["screencap"].as_string();
|
||||
emulator_info.adb.pullscreen = emulator_json["adb"]["pullscreen"].as_string();
|
||||
}
|
||||
emulator_info.x_offset = emulator_json.get("xOffset", 0);
|
||||
emulator_info.y_offset = emulator_json.get("yOffset", 0);
|
||||
emulator_info.right_offset = emulator_json.get("rightOffset", 0);
|
||||
emulator_info.bottom_offset = emulator_json.get("bottomOffset", 0);
|
||||
|
||||
emulator_info.width = DefaultWindowWidth + emulator_info.x_offset + emulator_info.right_offset;
|
||||
emulator_info.height = DefaultWindowHeight + emulator_info.y_offset + emulator_info.bottom_offset;
|
||||
|
||||
m_handles.emplace(name, std::move(emulator_info));
|
||||
}
|
||||
|
||||
for (json::value& rep : root["infrastOcrReplace"].as_array()) {
|
||||
m_infrast_ocr_replace.emplace(rep.as_array()[0].as_string(), rep.as_array()[1].as_string());
|
||||
}
|
||||
for (json::value& rep : root["recruitOcrReplace"].as_array()) {
|
||||
m_recruit_ocr_replace.emplace(rep.as_array()[0].as_string(), rep.as_array()[1].as_string());
|
||||
}
|
||||
DebugTrace("Load config succeed");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractConfiger.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
@@ -7,17 +9,17 @@
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace asst {
|
||||
class Configer
|
||||
class Configer : public AbstractConfiger
|
||||
{
|
||||
public:
|
||||
~Configer() = default;
|
||||
virtual ~Configer() = default;
|
||||
|
||||
static Configer& get_instance() {
|
||||
static Configer unique_instance;
|
||||
return unique_instance;
|
||||
}
|
||||
|
||||
bool load(const std::string& filename);
|
||||
//virtual bool load(const std::string& filename) override;
|
||||
|
||||
bool set_param(const std::string& type, const std::string& param, const std::string& value);
|
||||
|
||||
@@ -33,7 +35,7 @@ namespace asst {
|
||||
std::unordered_map<std::string, std::string> m_recruit_ocr_replace;
|
||||
std::unordered_map<std::string, std::string> m_infrast_ocr_replace;
|
||||
|
||||
private:
|
||||
protected:
|
||||
Configer() = default;
|
||||
Configer(const Configer& rhs) = default;
|
||||
Configer(Configer&& rhs) noexcept = default;
|
||||
@@ -41,6 +43,6 @@ namespace asst {
|
||||
Configer& operator=(const Configer& rhs) = default;
|
||||
Configer& operator=(Configer&& rhs) noexcept = default;
|
||||
|
||||
bool _load(const std::string& filename);
|
||||
virtual bool parse(json::value&& json) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,79 +9,42 @@
|
||||
|
||||
using namespace asst;
|
||||
|
||||
bool InfrastConfiger::load(const std::string& filename)
|
||||
bool InfrastConfiger::parse(json::value&& json)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Configer::load | ", filename);
|
||||
|
||||
InfrastConfiger temp;
|
||||
if (temp._load(filename)) {
|
||||
*this = std::move(temp);
|
||||
return true;
|
||||
json::value root = std::move(json);
|
||||
// 通用的干员信息
|
||||
for (json::value& name : root["allNames"].as_array())
|
||||
{
|
||||
m_all_opers_name.emplace(name.as_string());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
for (json::value& pair : root["featureKey"].as_array())
|
||||
{
|
||||
m_oper_name_feat.emplace(pair[0].as_string(), pair[1].as_string());
|
||||
}
|
||||
}
|
||||
|
||||
bool InfrastConfiger::_load(const std::string& filename)
|
||||
{
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return false;
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::string content(iss.str());
|
||||
|
||||
auto&& ret = json::parser::parse(content);
|
||||
if (!ret) {
|
||||
DebugTrace("parse error", content);
|
||||
return false;
|
||||
for (json::value& name : root["featureWhatever"].as_array())
|
||||
{
|
||||
m_oper_name_feat_whatever.emplace(name.as_string());
|
||||
}
|
||||
|
||||
json::value root = ret.value();
|
||||
try {
|
||||
// 通用的干员信息
|
||||
for (json::value& name : root["allNames"].as_array())
|
||||
// 每个基建设施中的干员组合信息
|
||||
for (json::value& facility : root["infrast"].as_array())
|
||||
{
|
||||
std::string key = facility["facility"].as_string();
|
||||
std::vector< std::vector<OperInfrastInfo>> combs_vec;
|
||||
for (json::value& comb : facility["combs"].as_array())
|
||||
{
|
||||
m_all_opers_name.emplace(name.as_string());
|
||||
}
|
||||
for (json::value& pair : root["featureKey"].as_array())
|
||||
{
|
||||
m_oper_name_feat.emplace(pair[0].as_string(), pair[1].as_string());
|
||||
}
|
||||
for (json::value& name : root["featureWhatever"].as_array())
|
||||
{
|
||||
m_oper_name_feat_whatever.emplace(name.as_string());
|
||||
}
|
||||
|
||||
// 每个基建设施中的干员组合信息
|
||||
for (json::value& facility : root["infrast"].as_array())
|
||||
{
|
||||
std::string key = facility["facility"].as_string();
|
||||
std::vector< std::vector<OperInfrastInfo>> combs_vec;
|
||||
for (json::value& comb : facility["combs"].as_array())
|
||||
{
|
||||
std::vector<OperInfrastInfo> opers;
|
||||
for (json::value& oper : comb["opers"].as_array()) {
|
||||
OperInfrastInfo info;
|
||||
info.name = oper["name"].as_string();
|
||||
info.elite = oper.get("elite", 0);
|
||||
info.level = oper.get("level", 0);
|
||||
opers.emplace_back(std::move(info));
|
||||
}
|
||||
combs_vec.emplace_back(std::move(opers));
|
||||
std::vector<OperInfrastInfo> opers;
|
||||
for (json::value& oper : comb["opers"].as_array()) {
|
||||
OperInfrastInfo info;
|
||||
info.name = oper["name"].as_string();
|
||||
info.elite = oper.get("elite", 0);
|
||||
info.level = oper.get("level", 0);
|
||||
opers.emplace_back(std::move(info));
|
||||
}
|
||||
m_infrast_combs.emplace(std::move(key), std::move(combs_vec));
|
||||
combs_vec.emplace_back(std::move(opers));
|
||||
}
|
||||
m_infrast_combs.emplace(std::move(key), std::move(combs_vec));
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
DebugTraceError("Load config json error!", e.what());
|
||||
return false;
|
||||
}
|
||||
DebugTrace("Load config succeed");
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractConfiger.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -7,24 +9,23 @@
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace asst {
|
||||
class InfrastConfiger
|
||||
class InfrastConfiger : public AbstractConfiger
|
||||
{
|
||||
public:
|
||||
~InfrastConfiger() = default;
|
||||
virtual ~InfrastConfiger() = default;
|
||||
|
||||
static InfrastConfiger& get_instance() {
|
||||
static InfrastConfiger unique_instance;
|
||||
return unique_instance;
|
||||
}
|
||||
|
||||
bool load(const std::string& filename);
|
||||
std::unordered_set<std::string> m_all_opers_name; // 所有干员的名字
|
||||
std::unordered_map<std::string, std::string> m_oper_name_feat; // 根据关键字需要特征检测干员名:如果OCR识别到了key的内容但是却没有value的内容,则进行特征检测进一步确认
|
||||
std::unordered_set<std::string> m_oper_name_feat_whatever; // 无论如何都进行特征检测的干员名
|
||||
|
||||
std::unordered_map<std::string, std::vector<std::vector<OperInfrastInfo>>> m_infrast_combs; // 各个设施内的可能干员组合
|
||||
|
||||
private:
|
||||
protected:
|
||||
InfrastConfiger() = default;
|
||||
InfrastConfiger(const InfrastConfiger& rhs) = default;
|
||||
InfrastConfiger(InfrastConfiger&& rhs) noexcept = default;
|
||||
@@ -32,6 +33,6 @@ namespace asst {
|
||||
InfrastConfiger& operator=(const InfrastConfiger& rhs) = default;
|
||||
InfrastConfiger& operator=(InfrastConfiger&& rhs) noexcept = default;
|
||||
|
||||
bool _load(const std::string& filename);
|
||||
virtual bool parse(json::value&& json) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\AsstCaller.h" />
|
||||
<ClInclude Include="..\include\AsstPort.h" />
|
||||
<ClInclude Include="AbstractConfiger.h" />
|
||||
<ClInclude Include="AbstractTask.h" />
|
||||
<ClInclude Include="Assistance.h" />
|
||||
<ClInclude Include="AsstAux.h" />
|
||||
@@ -37,6 +38,7 @@
|
||||
<ClInclude Include="WinMacro.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="AbstractConfiger.cpp" />
|
||||
<ClCompile Include="AbstractTask.cpp" />
|
||||
<ClCompile Include="ClickTask.cpp" />
|
||||
<ClCompile Include="IdentifyOperTask.cpp" />
|
||||
|
||||
@@ -114,6 +114,9 @@
|
||||
<ClInclude Include="SwipeTask.h">
|
||||
<Filter>头文件\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="AbstractConfiger.h">
|
||||
<Filter>头文件\Configer</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="WinMacro.cpp">
|
||||
@@ -167,6 +170,9 @@
|
||||
<ClCompile Include="SwipeTask.cpp">
|
||||
<Filter>源文件\Task</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AbstractConfiger.cpp">
|
||||
<Filter>源文件\Configer</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\resource\config.json">
|
||||
|
||||
@@ -10,72 +10,29 @@
|
||||
|
||||
using namespace asst;
|
||||
|
||||
bool RecruitConfiger::load(const std::string& filename)
|
||||
bool asst::RecruitConfiger::parse(json::value&& json)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("RecruitConfiger::load | ", filename);
|
||||
json::value root = std::move(json);
|
||||
for (json::value& oper : root.as_array()) {
|
||||
OperRecruitInfo oper_temp;
|
||||
oper_temp.name = oper["name"].as_string();
|
||||
oper_temp.type = oper["type"].as_string();
|
||||
m_all_types.emplace(oper_temp.type);
|
||||
// 职业类型也作为tag之一,加上"干员"两个字
|
||||
std::string type_as_tag = oper_temp.type + GbkToUtf8("干员");
|
||||
oper_temp.tags.emplace(type_as_tag);
|
||||
m_all_tags.emplace(std::move(type_as_tag));
|
||||
|
||||
RecruitConfiger temp;
|
||||
if (temp._load(filename)) {
|
||||
// 按干员等级排个序
|
||||
std::sort(temp.m_all_opers.begin(), temp.m_all_opers.end(), [](
|
||||
const auto& lhs,
|
||||
const auto& rhs)
|
||||
-> bool {
|
||||
return lhs.level > rhs.level;
|
||||
});
|
||||
*this = std::move(temp);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool asst::RecruitConfiger::_load(const std::string& filename)
|
||||
{
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return false;
|
||||
}
|
||||
std::stringstream iss;
|
||||
iss << ifs.rdbuf();
|
||||
ifs.close();
|
||||
std::string content(iss.str());
|
||||
|
||||
auto&& ret = json::parser::parse(content);
|
||||
if (!ret) {
|
||||
DebugTrace("parse error", content);
|
||||
return false;
|
||||
}
|
||||
|
||||
json::value root = ret.value();
|
||||
try {
|
||||
for (json::value& oper : root.as_array()) {
|
||||
OperRecruitInfo oper_temp;
|
||||
oper_temp.name = oper["name"].as_string();
|
||||
oper_temp.type = oper["type"].as_string();
|
||||
m_all_types.emplace(oper_temp.type);
|
||||
// 职业类型也作为tag之一,加上"干员"两个字
|
||||
std::string type_as_tag = oper_temp.type + GbkToUtf8("干员");
|
||||
oper_temp.tags.emplace(type_as_tag);
|
||||
m_all_tags.emplace(std::move(type_as_tag));
|
||||
|
||||
oper_temp.level = oper["level"].as_integer();
|
||||
oper_temp.sex = oper.get("sex", "unknown");
|
||||
for (const json::value& tag_value : oper["tags"].as_array()) {
|
||||
std::string tag = tag_value.as_string();
|
||||
oper_temp.tags.emplace(tag);
|
||||
m_all_tags.emplace(std::move(tag));
|
||||
}
|
||||
oper_temp.hidden = oper.get("hidden", false);
|
||||
oper_temp.name_en = oper.get("name-en", "unknown");
|
||||
m_all_opers.emplace_back(std::move(oper_temp));
|
||||
oper_temp.level = oper["level"].as_integer();
|
||||
oper_temp.sex = oper.get("sex", "unknown");
|
||||
for (const json::value& tag_value : oper["tags"].as_array()) {
|
||||
std::string tag = tag_value.as_string();
|
||||
oper_temp.tags.emplace(tag);
|
||||
m_all_tags.emplace(std::move(tag));
|
||||
}
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
DebugTraceError("Load config json error!", e.what());
|
||||
return false;
|
||||
oper_temp.hidden = oper.get("hidden", false);
|
||||
oper_temp.name_en = oper.get("name-en", "unknown");
|
||||
m_all_opers.emplace_back(std::move(oper_temp));
|
||||
}
|
||||
|
||||
//#ifdef LOG_TRACE
|
||||
@@ -84,7 +41,13 @@ bool asst::RecruitConfiger::_load(const std::string& filename)
|
||||
// }
|
||||
//#endif
|
||||
|
||||
DebugTrace("Load config succeed");
|
||||
// 按干员等级排个序
|
||||
std::sort(m_all_opers.begin(), m_all_opers.end(), [](
|
||||
const auto& lhs,
|
||||
const auto& rhs)
|
||||
-> bool {
|
||||
return lhs.level > rhs.level;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractConfiger.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
@@ -7,18 +9,16 @@
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace asst {
|
||||
class RecruitConfiger
|
||||
class RecruitConfiger : public AbstractConfiger
|
||||
{
|
||||
public:
|
||||
~RecruitConfiger() = default;
|
||||
virtual ~RecruitConfiger() = default;
|
||||
|
||||
static RecruitConfiger& get_instance() {
|
||||
static RecruitConfiger unique_instance;
|
||||
return unique_instance;
|
||||
}
|
||||
|
||||
bool load(const std::string& filename);
|
||||
|
||||
std::unordered_set<std::string> m_all_tags;
|
||||
std::unordered_set<std::string> m_all_types;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace asst {
|
||||
|
||||
constexpr static int CorrectNumberOfTags = 5;
|
||||
|
||||
private:
|
||||
protected:
|
||||
RecruitConfiger() = default;
|
||||
RecruitConfiger(const RecruitConfiger& rhs) = default;
|
||||
RecruitConfiger(RecruitConfiger&& rhs) noexcept = default;
|
||||
@@ -34,6 +34,6 @@ namespace asst {
|
||||
RecruitConfiger& operator=(const RecruitConfiger& rhs) = default;
|
||||
RecruitConfiger& operator=(RecruitConfiger&& rhs) noexcept = default;
|
||||
|
||||
bool _load(const std::string& filename);
|
||||
virtual bool parse(json::value&& json) override;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user