diff --git a/src/MeoAssistant/AbstractConfiger.cpp b/src/MeoAssistant/AbstractConfiger.cpp index 21856c790a..a6195cdc4c 100644 --- a/src/MeoAssistant/AbstractConfiger.cpp +++ b/src/MeoAssistant/AbstractConfiger.cpp @@ -40,5 +40,4 @@ bool asst::AbstractConfiger::load(const std::string& filename) m_last_error = std::string("json field error ") + e.what(); return false; } - return true; } diff --git a/src/MeoAssistant/AbstractTask.cpp b/src/MeoAssistant/AbstractTask.cpp index cbecb4c924..d47ff29ad1 100644 --- a/src/MeoAssistant/AbstractTask.cpp +++ b/src/MeoAssistant/AbstractTask.cpp @@ -170,12 +170,12 @@ bool AbstractTask::save_image(const cv::Mat& image, const std::string& dir) bool asst::AbstractTask::need_exit() const { - return m_exit_flag != nullptr && *m_exit_flag == true; + return m_exit_flag != nullptr && *m_exit_flag; } void asst::AbstractTask::callback(AsstMsg msg, const json::value& detail) { - for (TaskPluginPtr plugin : m_plugins) { + for (const TaskPluginPtr& plugin : m_plugins) { plugin->set_exit_flag(m_exit_flag); plugin->set_ctrler(m_ctrler); plugin->set_task_id(m_task_id); diff --git a/src/MeoAssistant/AbstractTask.h b/src/MeoAssistant/AbstractTask.h index 6d768ab051..1daef105ec 100644 --- a/src/MeoAssistant/AbstractTask.h +++ b/src/MeoAssistant/AbstractTask.h @@ -67,7 +67,7 @@ namespace asst json::value basic_info_with_what(std::string what) const; bool sleep(unsigned millisecond); bool need_exit() const; - bool save_image(const cv::Mat& image, const std::string& dir); + static bool save_image(const cv::Mat& image, const std::string& dir); bool m_enable = true; bool m_ignore_error = true; diff --git a/src/MeoAssistant/Assistant.cpp b/src/MeoAssistant/Assistant.cpp index a8cb14a2f3..8d99dc9358 100644 --- a/src/MeoAssistant/Assistant.cpp +++ b/src/MeoAssistant/Assistant.cpp @@ -82,43 +82,29 @@ asst::Assistant::TaskId asst::Assistant::append_task(const std::string& type, co std::shared_ptr ptr = nullptr; - if (type == FightTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == StartUpTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == AwardTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == VisitTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == MallTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == InfrastTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == RecruitTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == RoguelikeTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } - else if (type == CopilotTask::TaskType) { - ptr = std::make_shared(task_callback, static_cast(this)); - } +#define ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(TASK) \ +else if (type == TASK::TaskType) { ptr = std::make_shared(task_callback, static_cast(this)); } + + if (false) {} + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(FightTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(StartUpTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(AwardTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(VisitTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(MallTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(InfrastTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(RecruitTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(RoguelikeTask) + ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH(CopilotTask) #ifdef ASST_DEBUG - else if (type == DebugTask::TaskType) { - ptr = std::make_shared(task_callback, (void*)this); - } + ASST_ASSISTANT_APPEND_TASK_FROM_TYPE_IF_BRANCH(DebugTask) #endif else { Log.error(__FUNCTION__, "| invalid type:", type); return 0; } +#undef ASST_ASSISTANT_APPEND_TASK_FROM_STRING_IF_BRANCH + bool params_ret = ptr->set_params(ret.value()); if (!params_ret) { return 0; diff --git a/src/MeoAssistant/AsstInfrastDef.h b/src/MeoAssistant/AsstInfrastDef.h index d9dc871c90..da492022d8 100644 --- a/src/MeoAssistant/AsstInfrastDef.h +++ b/src/MeoAssistant/AsstInfrastDef.h @@ -2,53 +2,50 @@ #include "AsstTypes.h" -namespace asst +namespace asst::infrast { - namespace infrast + struct Facility { - struct Facility - { - ::std::string id; - ::std::vector<::std::string> products; - int max_num_of_opers = 0; - }; + ::std::string id; + ::std::vector<::std::string> products; + int max_num_of_opers = 0; + }; - enum class SmileyType - { - Invalid = -1, - Rest, // 休息完成,绿色笑脸 - Work, // 工作中,黄色笑脸 - Distract // 注意力涣散,红色哭脸 - }; - struct Smiley - { - SmileyType type = SmileyType::Invalid; - Rect rect; - }; - enum class Doing // 正在做什么 - { - Invalid = -1, - Nothing, // 什么都不在做,也不在休息也不在工作 - Resting, // 休息中 - Working // 工作中 - }; + enum class SmileyType + { + Invalid = -1, + Rest, // 休息完成,绿色笑脸 + Work, // 工作中,黄色笑脸 + Distract // 注意力涣散,红色哭脸 + }; + struct Smiley + { + SmileyType type = SmileyType::Invalid; + Rect rect; + }; + enum class Doing // 正在做什么 + { + Invalid = -1, + Nothing, // 什么都不在做,也不在休息也不在工作 + Resting, // 休息中 + Working // 工作中 + }; - struct Skill - { - ::std::string id; - ::std::string templ_name; - ::std::vector<::std::string> names; // 很多基建技能是一样的,就是名字不同。所以一个技能id可能对应多个名字 - ::std::string desc; - ::std::unordered_map<::std::string, double> efficient; // 技能效率,key:产品名(赤金、经验书等), value: 效率数值 - ::std::unordered_map<::std::string, ::std::string> efficient_regex; // 技能效率正则,key:产品名(赤金、经验书等), value: 效率正则。如不为空,会先对正则进行计算,再加上efficient里面的值 - int max_num = INT_MAX; // 最多选几个该技能 + struct Skill + { + ::std::string id; + ::std::string templ_name; + ::std::vector<::std::string> names; // 很多基建技能是一样的,就是名字不同。所以一个技能id可能对应多个名字 + ::std::string desc; + ::std::unordered_map<::std::string, double> efficient; // 技能效率,key:产品名(赤金、经验书等), value: 效率数值 + ::std::unordered_map<::std::string, ::std::string> efficient_regex; // 技能效率正则,key:产品名(赤金、经验书等), value: 效率正则。如不为空,会先对正则进行计算,再加上efficient里面的值 + int max_num = INT_MAX; // 最多选几个该技能 - bool operator==(const Skill& skill) const noexcept - { - return id == skill.id; - } - }; - } + bool operator==(const Skill& skill) const noexcept + { + return id == skill.id; + } + }; } namespace std @@ -64,67 +61,64 @@ namespace std }; } -namespace asst +namespace asst::infrast { - namespace infrast + struct BattleRealTimeOper { - struct BattleRealTimeOper - { - ::std::string face_hash; // 有些干员的技能是完全一样的,做个hash区分一下不同干员 - ::std::string name_hash; // 预留 - Smiley smiley; - double mood_ratio = 0; // 心情进度条的百分比 - Doing doing = Doing::Invalid; - bool selected = false; // 干员是否已被选择(蓝色的选择框) - ::std::unordered_set skills; - Rect rect; - }; + ::std::string face_hash; // 有些干员的技能是完全一样的,做个hash区分一下不同干员 + ::std::string name_hash; // 预留 + Smiley smiley; + double mood_ratio = 0; // 心情进度条的百分比 + Doing doing = Doing::Invalid; + bool selected = false; // 干员是否已被选择(蓝色的选择框) + ::std::unordered_set skills; + Rect rect; + }; - struct SkillsComb + struct SkillsComb + { + SkillsComb() = default; + SkillsComb(std::unordered_set skill_vec) { - SkillsComb() = default; - SkillsComb(std::unordered_set skill_vec) - { - skills = ::std::move(skill_vec); - for (const auto& s : skills) { - for (const auto& [key, value] : s.efficient) { - efficient[key] += value; - } - for (const auto& [key, reg] : s.efficient_regex) { - efficient_regex[key] += "+(" + reg + ")"; - } + skills = ::std::move(skill_vec); + for (const auto& s : skills) { + for (const auto& [key, value] : s.efficient) { + efficient[key] += value; + } + for (const auto& [key, reg] : s.efficient_regex) { + efficient_regex[key] += "+(" + reg + ")"; } } - bool operator==(const SkillsComb& rhs) const - { - return skills == rhs.skills; - } - - ::std::string desc; - ::std::unordered_set skills; - ::std::unordered_map efficient; - ::std::unordered_map efficient_regex; - - ::std::string name_hash; - bool hash_filter = false; - ::std::unordered_map possible_hashs; // 限定只允许某些hash匹配的某些干员。若hash不相同,即使技能匹配了也不可用。hashs若为空,则不生效 - }; - // 基建技能组 - struct SkillsGroup + } + bool operator==(const SkillsComb& rhs) const { - ::std::string desc; // 文字介绍,实际不起作用 - ::std::unordered_map conditions; // 技能组合可用条件,例如:key 发电站数量,value 3 - ::std::vector necessary; // 必选技能。这里面的缺少任一,则该技能组合不可用 - ::std::vector optional; // 可选技能。 - bool allow_external = false; // 当干员数没满3个的时候,是否允许补充外部干员 - }; + return skills == rhs.skills; + } - enum class WorkMode - { - Invalid = -1, - Gentle, // 温和换班模式:会对干员人数不满的设施进行换班,计算单设施内最优解,尽量不破坏原有的干员组合;即若设施内干员是满的,则不对该设施进行换班 - Aggressive, // 激进换班模式:会对每一个设施进行换班,计算单设施内最优解,但不会将其他设施中的干员替换过来;即按工作状态排序,仅选择前面的干员 - Extreme // 偏激换班模式:会对每一个设施进行换班,计算全局的单设施内最优解,为追求更高效率,会将其他设施内的干员也替换过来;即按技能排序,计算所有拥有该设施技能的干员效率,无论他在不在其他地方工作 - }; - } + ::std::string desc; + ::std::unordered_set skills; + ::std::unordered_map efficient; + ::std::unordered_map efficient_regex; + + ::std::string name_hash; + bool hash_filter = false; + ::std::unordered_map possible_hashs; // 限定只允许某些hash匹配的某些干员。若hash不相同,即使技能匹配了也不可用。hashs若为空,则不生效 + }; + // 基建技能组 + struct SkillsGroup + { + ::std::string desc; // 文字介绍,实际不起作用 + ::std::unordered_map conditions; // 技能组合可用条件,例如:key 发电站数量,value 3 + ::std::vector necessary; // 必选技能。这里面的缺少任一,则该技能组合不可用 + ::std::vector optional; // 可选技能。 + bool allow_external = false; // 当干员数没满3个的时候,是否允许补充外部干员 + }; + + enum class WorkMode + { + Invalid = -1, + Gentle, // 温和换班模式:会对干员人数不满的设施进行换班,计算单设施内最优解,尽量不破坏原有的干员组合;即若设施内干员是满的,则不对该设施进行换班 + Aggressive, // 激进换班模式:会对每一个设施进行换班,计算单设施内最优解,但不会将其他设施中的干员替换过来;即按工作状态排序,仅选择前面的干员 + Extreme // 偏激换班模式:会对每一个设施进行换班,计算全局的单设施内最优解,为追求更高效率,会将其他设施内的干员也替换过来;即按技能排序,计算所有拥有该设施技能的干员效率,无论他在不在其他地方工作 + }; } diff --git a/src/MeoAssistant/AsstUtils.hpp b/src/MeoAssistant/AsstUtils.hpp index d7570ef703..165b6fe200 100644 --- a/src/MeoAssistant/AsstUtils.hpp +++ b/src/MeoAssistant/AsstUtils.hpp @@ -15,299 +15,296 @@ #include #endif -namespace asst +namespace asst::utils { - namespace utils + inline std::string string_replace_all(const std::string& src, const std::string& old_value, const std::string& new_value) { - inline std::string string_replace_all(const std::string& src, const std::string& old_value, const std::string& new_value) - { - std::string str = src; - for (std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()) { - if ((pos = str.find(old_value, pos)) != std::string::npos) - str.replace(pos, old_value.length(), new_value); - else - break; - } - return str; + std::string str = src; + for (std::string::size_type pos(0); pos != std::string::npos; pos += new_value.length()) { + if ((pos = str.find(old_value, pos)) != std::string::npos) + str.replace(pos, old_value.length(), new_value); + else + break; } + return str; + } - inline std::string string_replace_all_batch(const std::string& src, const std::vector>& replace_pairs) - { - std::string str = src; - for (auto& [old_value, new_value] : replace_pairs) { - str = string_replace_all(str, old_value, new_value); - } - return str; + inline std::string string_replace_all_batch(const std::string& src, const std::vector>& replace_pairs) + { + std::string str = src; + for (auto& [old_value, new_value] : replace_pairs) { + str = string_replace_all(str, old_value, new_value); } + return str; + } - inline std::vector string_split(const std::string& str, const std::string& delimiter) - { - std::string::size_type pos1 = 0; - std::string::size_type pos2 = str.find(delimiter); - std::vector result; + inline std::vector string_split(const std::string& str, const std::string& delimiter) + { + std::string::size_type pos1 = 0; + std::string::size_type pos2 = str.find(delimiter); + std::vector result; - while (std::string::npos != pos2) { - result.emplace_back(str.substr(pos1, pos2 - pos1)); + while (std::string::npos != pos2) { + result.emplace_back(str.substr(pos1, pos2 - pos1)); - pos1 = pos2 + delimiter.size(); - pos2 = str.find(delimiter, pos1); - } - if (pos1 != str.length()) - result.emplace_back(str.substr(pos1)); - - return result; + pos1 = pos2 + delimiter.size(); + pos2 = str.find(delimiter, pos1); } + if (pos1 != str.length()) + result.emplace_back(str.substr(pos1)); - inline std::string get_format_time() - { - char buff[128] = { 0 }; + return result; + } + + inline std::string get_format_time() + { + char buff[128] = { 0 }; #ifdef _WIN32 - SYSTEMTIME curtime; - GetLocalTime(&curtime); + SYSTEMTIME curtime; + GetLocalTime(&curtime); #ifdef _MSC_VER - sprintf_s(buff, sizeof(buff), + sprintf_s(buff, sizeof(buff), #else // ! _MSC_VER - sprintf(buff, + sprintf(buff, #endif // END _MSC_VER - "%04d-%02d-%02d %02d:%02d:%02d.%03d", - curtime.wYear, curtime.wMonth, curtime.wDay, - curtime.wHour, curtime.wMinute, curtime.wSecond, curtime.wMilliseconds); + "%04d-%02d-%02d %02d:%02d:%02d.%03d", + curtime.wYear, curtime.wMonth, curtime.wDay, + curtime.wHour, curtime.wMinute, curtime.wSecond, curtime.wMilliseconds); #else // ! _WIN32 - struct timeval tv{}; - gettimeofday(&tv, nullptr); - time_t nowtime = tv.tv_sec; - struct tm* tm_info = localtime(&nowtime); - strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", tm_info); - sprintf(buff, "%s.%03ld", buff, tv.tv_usec / 1000); + struct timeval tv{}; + gettimeofday(&tv, nullptr); + time_t nowtime = tv.tv_sec; + struct tm* tm_info = localtime(&nowtime); + strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", tm_info); + sprintf(buff, "%s.%03ld", buff, tv.tv_usec / 1000); #endif // END _WIN32 - return buff; - } + return buff; + } - inline std::string ansi_to_utf8(const std::string& ansi_str) - { + inline std::string ansi_to_utf8(const std::string& ansi_str) + { #ifdef _WIN32 - const char* src_str = ansi_str.c_str(); - int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, nullptr, 0); - const std::size_t wstr_length = static_cast(len) + 1U; - auto wstr = new wchar_t[wstr_length]; - memset(wstr, 0, sizeof(wstr[0]) * wstr_length); - MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len); + const char* src_str = ansi_str.c_str(); + int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, nullptr, 0); + const std::size_t wstr_length = static_cast(len) + 1U; + auto wstr = new wchar_t[wstr_length]; + memset(wstr, 0, sizeof(wstr[0]) * wstr_length); + MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len); - len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr); - const std::size_t str_length = static_cast(len) + 1; - auto str = new char[str_length]; - memset(str, 0, sizeof(str[0]) * str_length); - WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, nullptr, nullptr); - std::string strTemp = str; + len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr); + const std::size_t str_length = static_cast(len) + 1; + auto str = new char[str_length]; + memset(str, 0, sizeof(str[0]) * str_length); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, nullptr, nullptr); + std::string strTemp = str; - delete[] wstr; - wstr = nullptr; - delete[] str; - str = nullptr; + delete[] wstr; + wstr = nullptr; + delete[] str; + str = nullptr; - return strTemp; + return strTemp; #else // Don't fucking use gbk in linux! - return ansi_str; + return ansi_str; #endif - } + } - inline std::string utf8_to_ansi(const std::string& utf8_str) - { + inline std::string utf8_to_ansi(const std::string& utf8_str) + { #ifdef _WIN32 - const char* src_str = utf8_str.c_str(); - int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, nullptr, 0); - const std::size_t wsz_ansi_length = static_cast(len) + 1; - auto wsz_ansi = new wchar_t[wsz_ansi_length]; - memset(wsz_ansi, 0, sizeof(wsz_ansi[0]) * wsz_ansi_length); - MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wsz_ansi, len); + const char* src_str = utf8_str.c_str(); + int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, nullptr, 0); + const std::size_t wsz_ansi_length = static_cast(len) + 1; + auto wsz_ansi = new wchar_t[wsz_ansi_length]; + memset(wsz_ansi, 0, sizeof(wsz_ansi[0]) * wsz_ansi_length); + MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wsz_ansi, len); - len = WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, nullptr, 0, nullptr, nullptr); - const std::size_t sz_ansi_length = static_cast(len) + 1; - auto sz_ansi = new char[sz_ansi_length]; - memset(sz_ansi, 0, sizeof(sz_ansi[0]) * sz_ansi_length); - WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, sz_ansi, len, nullptr, nullptr); - std::string strTemp(sz_ansi); + len = WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, nullptr, 0, nullptr, nullptr); + const std::size_t sz_ansi_length = static_cast(len) + 1; + auto sz_ansi = new char[sz_ansi_length]; + memset(sz_ansi, 0, sizeof(sz_ansi[0]) * sz_ansi_length); + WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, sz_ansi, len, nullptr, nullptr); + std::string strTemp(sz_ansi); - delete[] wsz_ansi; - wsz_ansi = nullptr; - delete[] sz_ansi; - sz_ansi = nullptr; + delete[] wsz_ansi; + wsz_ansi = nullptr; + delete[] sz_ansi; + sz_ansi = nullptr; - return strTemp; + return strTemp; #else // Don't fucking use gbk in linux! - return utf8_str; + return utf8_str; #endif + } + + template + constexpr inline RetTy make_rect(const ArgType& rect) + { + return RetTy{ rect.x, rect.y, rect.width, rect.height }; + } + + inline std::string load_file_without_bom(const std::string& filename) + { + std::ifstream ifs(filename, std::ios::in); + if (!ifs.is_open()) { + return {}; } + std::stringstream iss; + iss << ifs.rdbuf(); + ifs.close(); + std::string str = iss.str(); - template - constexpr inline RetTy make_rect(const ArgType& rect) - { - return RetTy{ rect.x, rect.y, rect.width, rect.height }; - } + using uchar = unsigned char; + constexpr static uchar Bom_0 = 0xEF; + constexpr static uchar Bom_1 = 0xBB; + constexpr static uchar Bom_2 = 0xBF; - inline std::string load_file_without_bom(const std::string& filename) - { - std::ifstream ifs(filename, std::ios::in); - if (!ifs.is_open()) { - return {}; - } - std::stringstream iss; - iss << ifs.rdbuf(); - ifs.close(); - std::string str = iss.str(); - - using uchar = unsigned char; - constexpr static uchar Bom_0 = 0xEF; - constexpr static uchar Bom_1 = 0xBB; - constexpr static uchar Bom_2 = 0xBF; - - if (str.size() >= 3 && static_cast(str.at(0)) == Bom_0 && static_cast(str.at(1)) == Bom_1 && static_cast(str.at(2)) == Bom_2) { - str.assign(str.begin() + 3, str.end()); - return str; - } + if (str.size() >= 3 && static_cast(str.at(0)) == Bom_0 && static_cast(str.at(1)) == Bom_1 && static_cast(str.at(2)) == Bom_2) { + str.assign(str.begin() + 3, str.end()); return str; } + return str; + } - inline std::string callcmd(const std::string& cmdline) - { - constexpr int PipeBuffSize = 4096; - std::string pipe_str; - auto pipe_buffer = std::make_unique(PipeBuffSize); + inline std::string callcmd(const std::string& cmdline) + { + constexpr int PipeBuffSize = 4096; + std::string pipe_str; + auto pipe_buffer = std::make_unique(PipeBuffSize); #ifdef _WIN32 - SECURITY_ATTRIBUTES pipe_sec_attr = { 0 }; - pipe_sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES); - pipe_sec_attr.lpSecurityDescriptor = nullptr; - pipe_sec_attr.bInheritHandle = TRUE; - HANDLE pipe_read = nullptr; - HANDLE pipe_child_write = nullptr; - CreatePipe(&pipe_read, &pipe_child_write, &pipe_sec_attr, PipeBuffSize); + SECURITY_ATTRIBUTES pipe_sec_attr = { 0 }; + pipe_sec_attr.nLength = sizeof(SECURITY_ATTRIBUTES); + pipe_sec_attr.lpSecurityDescriptor = nullptr; + pipe_sec_attr.bInheritHandle = TRUE; + HANDLE pipe_read = nullptr; + HANDLE pipe_child_write = nullptr; + CreatePipe(&pipe_read, &pipe_child_write, &pipe_sec_attr, PipeBuffSize); - STARTUPINFOA si = { 0 }; - si.cb = sizeof(STARTUPINFO); - si.dwFlags = STARTF_USESTDHANDLES; - si.wShowWindow = SW_HIDE; - si.hStdOutput = pipe_child_write; - si.hStdError = pipe_child_write; + STARTUPINFOA si = { 0 }; + si.cb = sizeof(STARTUPINFO); + si.dwFlags = STARTF_USESTDHANDLES; + si.wShowWindow = SW_HIDE; + si.hStdOutput = pipe_child_write; + si.hStdError = pipe_child_write; - PROCESS_INFORMATION pi = { nullptr }; + PROCESS_INFORMATION pi = { nullptr }; - BOOL p_ret = CreateProcessA(nullptr, const_cast(cmdline.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi); - if (p_ret) { - DWORD peek_num = 0; - DWORD read_num = 0; - do { - while (::PeekNamedPipe(pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) { - if (::ReadFile(pipe_read, pipe_buffer.get(), peek_num, &read_num, nullptr)) { - pipe_str.append(pipe_buffer.get(), pipe_buffer.get() + read_num); - } - } - } while (::WaitForSingleObject(pi.hProcess, 0) == WAIT_TIMEOUT); - - DWORD exit_ret = 255; - ::GetExitCodeProcess(pi.hProcess, &exit_ret); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } - - ::CloseHandle(pipe_read); - ::CloseHandle(pipe_child_write); - -#else - constexpr static int PIPE_READ = 0; - constexpr static int PIPE_WRITE = 1; - int pipe_in[2] = { 0 }; - int pipe_out[2] = { 0 }; - int pipe_in_ret = pipe(pipe_in); - int pipe_out_ret = pipe(pipe_out); - fcntl(pipe_out[PIPE_READ], F_SETFL, O_NONBLOCK); - int exit_ret = 0; - int child = fork(); - if (child == 0) { - // child process - dup2(pipe_in[PIPE_READ], STDIN_FILENO); - dup2(pipe_out[PIPE_WRITE], STDOUT_FILENO); - dup2(pipe_out[PIPE_WRITE], STDERR_FILENO); - - // all these are for use by parent only - close(pipe_in[PIPE_READ]); - close(pipe_in[PIPE_WRITE]); - close(pipe_out[PIPE_READ]); - close(pipe_out[PIPE_WRITE]); - - exit_ret = execlp("sh", "sh", "-c", cmdline.c_str(), nullptr); - exit(exit_ret); - } - else if (child > 0) { - // parent process - - // close unused file descriptors, these are for child only - close(pipe_in[PIPE_READ]); - close(pipe_out[PIPE_WRITE]); - - do { - ssize_t read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize); - - while (read_num > 0) { + BOOL p_ret = CreateProcessA(nullptr, const_cast(cmdline.c_str()), nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi); + if (p_ret) { + DWORD peek_num = 0; + DWORD read_num = 0; + do { + while (::PeekNamedPipe(pipe_read, nullptr, 0, nullptr, &peek_num, nullptr) && peek_num > 0) { + if (::ReadFile(pipe_read, pipe_buffer.get(), peek_num, &read_num, nullptr)) { pipe_str.append(pipe_buffer.get(), pipe_buffer.get() + read_num); - read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize); - }; - } while (::waitpid(child, &exit_ret, WNOHANG) == 0); + } + } + } while (::WaitForSingleObject(pi.hProcess, 0) == WAIT_TIMEOUT); - close(pipe_in[PIPE_WRITE]); - close(pipe_out[PIPE_READ]); - } - else { - // failed to create child process - close(pipe_in[PIPE_READ]); - close(pipe_in[PIPE_WRITE]); - close(pipe_out[PIPE_READ]); - close(pipe_out[PIPE_WRITE]); - } -#endif - return pipe_str; + DWORD exit_ret = 255; + ::GetExitCodeProcess(pi.hProcess, &exit_ret); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); } - // template::value>::type> - // std::string VectorToString(const std::vector& vector, bool to_gbk = false) { - // if (vector.empty()) { - // return std::string(); - // } - // static const std::string inter = ", "; - // std::string str; - // for (const T& ele : vector) { - // if (to_gbk) { - // str += utils::utf8_to_ansi(ele) + inter; - // } - // else { - // str += ele + inter; - // } - // } + ::CloseHandle(pipe_read); + ::CloseHandle(pipe_child_write); - // if (!str.empty()) { - // str.erase(str.size() - inter.size(), inter.size()); - // } - // return str; - //} +#else + constexpr static int PIPE_READ = 0; + constexpr static int PIPE_WRITE = 1; + int pipe_in[2] = { 0 }; + int pipe_out[2] = { 0 }; + int pipe_in_ret = pipe(pipe_in); + int pipe_out_ret = pipe(pipe_out); + fcntl(pipe_out[PIPE_READ], F_SETFL, O_NONBLOCK); + int exit_ret = 0; + int child = fork(); + if (child == 0) { + // child process + dup2(pipe_in[PIPE_READ], STDIN_FILENO); + dup2(pipe_out[PIPE_WRITE], STDOUT_FILENO); + dup2(pipe_out[PIPE_WRITE], STDERR_FILENO); - //template::value>::type> - // std::string VectorToString(const std::vector& vector) { - // if (vector.empty()) { - // return std::string(); - // } - // static const std::string inter = ", "; - // std::string str; - // for (const T& ele : vector) { - // str += std::to_string(ele) + inter; - // } + // all these are for use by parent only + close(pipe_in[PIPE_READ]); + close(pipe_in[PIPE_WRITE]); + close(pipe_out[PIPE_READ]); + close(pipe_out[PIPE_WRITE]); - // if (!str.empty()) { - // str.erase(str.size() - inter.size(), inter.size()); - // } - // return str; - //} + exit_ret = execlp("sh", "sh", "-c", cmdline.c_str(), nullptr); + exit(exit_ret); + } + else if (child > 0) { + // parent process + + // close unused file descriptors, these are for child only + close(pipe_in[PIPE_READ]); + close(pipe_out[PIPE_WRITE]); + + do { + ssize_t read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize); + + while (read_num > 0) { + pipe_str.append(pipe_buffer.get(), pipe_buffer.get() + read_num); + read_num = read(pipe_out[PIPE_READ], pipe_buffer.get(), PipeBuffSize); + }; + } while (::waitpid(child, &exit_ret, WNOHANG) == 0); + + close(pipe_in[PIPE_WRITE]); + close(pipe_out[PIPE_READ]); + } + else { + // failed to create child process + close(pipe_in[PIPE_READ]); + close(pipe_in[PIPE_WRITE]); + close(pipe_out[PIPE_READ]); + close(pipe_out[PIPE_WRITE]); + } +#endif + return pipe_str; } + + // template::value>::type> + // std::string VectorToString(const std::vector& vector, bool to_gbk = false) { + // if (vector.empty()) { + // return std::string(); + // } + // static const std::string inter = ", "; + // std::string str; + // for (const T& ele : vector) { + // if (to_gbk) { + // str += utils::utf8_to_ansi(ele) + inter; + // } + // else { + // str += ele + inter; + // } + // } + + // if (!str.empty()) { + // str.erase(str.size() - inter.size(), inter.size()); + // } + // return str; + //} + + //template::value>::type> + // std::string VectorToString(const std::vector& vector) { + // if (vector.empty()) { + // return std::string(); + // } + // static const std::string inter = ", "; + // std::string str; + // for (const T& ele : vector) { + // str += std::to_string(ele) + inter; + // } + + // if (!str.empty()) { + // str.erase(str.size() - inter.size(), inter.size()); + // } + // return str; + //} } diff --git a/src/MeoAssistant/Controller.cpp b/src/MeoAssistant/Controller.cpp index a70f0d5c06..893e45c643 100644 --- a/src/MeoAssistant/Controller.cpp +++ b/src/MeoAssistant/Controller.cpp @@ -57,7 +57,7 @@ private: asst::Controller::Controller(AsstCallback callback, void* callback_arg) : m_callback(std::move(callback)), m_callback_arg(callback_arg), - m_rand_engine(static_cast(time(nullptr))) + m_rand_engine(std::random_device{}()) { LogTraceFunction; @@ -242,7 +242,7 @@ void asst::Controller::pipe_working_proc() } } -std::optional> asst::Controller::call_command(const std::string& cmd, int64_t timeout, bool recv_by_socket) +std::optional> asst::Controller::call_command(const std::string& cmd, int64_t timeout, bool recv_by_socket) { LogTraceScope(std::string(__FUNCTION__) + " | `" + cmd + "`"); @@ -400,20 +400,19 @@ std::optional> asst::Controller::call_command(const s return std::nullopt; } -void asst::Controller::convert_lf(std::vector& data) +void asst::Controller::convert_lf(std::vector& data) { LogTraceFunction; if (data.empty() || data.size() < 2) { return; } - using Iter = std::vector::iterator; - auto pred = [](const Iter& cur) -> bool { + auto pred = [](const std::vector::iterator& cur) -> bool { return *cur == '\r' && *(cur + 1) == '\n'; }; // find the first of "\r\n" - Iter first_iter = data.end(); - for (Iter iter = data.begin(); iter != data.end() - 1; ++iter) { + auto first_iter = data.end(); + for (auto iter = data.begin(); iter != data.end() - 1; ++iter) { if (pred(iter)) { first_iter = iter; break; @@ -423,8 +422,8 @@ void asst::Controller::convert_lf(std::vector& data) return; } // move forward all non-crlf elements - Iter end_r1_iter = data.end() - 1; - Iter next_iter = first_iter; + auto end_r1_iter = data.end() - 1; + auto next_iter = first_iter; while (++first_iter != end_r1_iter) { if (!pred(first_iter)) { *next_iter = *first_iter; @@ -464,7 +463,7 @@ void asst::Controller::random_delay() const auto& opt = Resrc.cfg().get_options(); if (opt.control_delay_upper != 0) { LogTraceFunction; - static std::default_random_engine rand_engine(static_cast(time(nullptr))); + static std::default_random_engine rand_engine(std::random_device{}()); static std::uniform_int_distribution rand_uni( opt.control_delay_lower, opt.control_delay_upper); @@ -500,7 +499,7 @@ int asst::Controller::push_cmd(const std::string& cmd) std::unique_lock lock(m_cmd_queue_mutex); m_cmd_queue.emplace(cmd); m_cmd_condvar.notify_one(); - return ++m_push_id; + return int(++m_push_id); } std::optional asst::Controller::try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times) @@ -635,7 +634,7 @@ bool asst::Controller::screencap() { Log.info("Try to find the fastest way to screencap"); m_inited = false; - auto min_cost = std::chrono::nanoseconds(MAXLONGLONG); + auto min_cost = std::chrono::nanoseconds(LLONG_MAX); auto start_time = std::chrono::high_resolution_clock::now(); if (m_support_socket && m_server_started && @@ -1168,8 +1167,6 @@ bool asst::Controller::release() #ifndef _WIN32 if (m_child) -#else - if (true) #endif { return call_command(m_adb.release).has_value(); diff --git a/src/MeoAssistant/Controller.h b/src/MeoAssistant/Controller.h index 448c2dc2c9..cbb044fdf7 100644 --- a/src/MeoAssistant/Controller.h +++ b/src/MeoAssistant/Controller.h @@ -64,7 +64,7 @@ namespace asst private: void pipe_working_proc(); - std::optional> call_command(const std::string& cmd, int64_t timeout = 20000, bool recv_by_socket = false); + std::optional> call_command(const std::string& cmd, int64_t timeout = 20000, bool recv_by_socket = false); int push_cmd(const std::string& cmd); std::optional try_to_init_socket(const std::string& local_address, unsigned short try_port, unsigned short try_times = 10U); @@ -81,7 +81,7 @@ namespace asst void clear_info() noexcept; // 转换data中所有的crlf为lf:有些模拟器自带的adb,exec-out输出的\n,会被替换成\r\n,导致解码错误,所以这里转一下回来(点名批评mumu) - static void convert_lf(std::vector& data); + static void convert_lf(std::vector& data); AsstCallback m_callback; void* m_callback_arg = nullptr; diff --git a/src/MeoAssistant/InfrastConfiger.cpp b/src/MeoAssistant/InfrastConfiger.cpp index fc67284ad5..899c00c9db 100644 --- a/src/MeoAssistant/InfrastConfiger.cpp +++ b/src/MeoAssistant/InfrastConfiger.cpp @@ -10,7 +10,7 @@ bool asst::InfrastConfiger::parse(const json::value& json) for (const json::value& facility : json.at("facility").as_array()) { std::string facility_name = facility.as_string(); - json::value facility_json = json.at(facility_name); + const json::value& facility_json = json.at(facility_name); std::vector products; for (const json::value& product_json : facility_json.at("products").as_array()) { diff --git a/src/MeoAssistant/Logger.hpp b/src/MeoAssistant/Logger.hpp index 55957fbd7e..590308051c 100644 --- a/src/MeoAssistant/Logger.hpp +++ b/src/MeoAssistant/Logger.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -202,8 +203,8 @@ namespace asst class LoggerAux { public: - LoggerAux(const std::string& func_name) - : m_func_name(func_name), + LoggerAux(std::string func_name) + : m_func_name(std::move(func_name)), m_start_time(std::chrono::steady_clock::now()) { Logger::get_instance().trace(m_func_name, " | enter"); diff --git a/src/MeoAssistant/ProcessTask.cpp b/src/MeoAssistant/ProcessTask.cpp index 0816a79a5f..d64a8d7872 100644 --- a/src/MeoAssistant/ProcessTask.cpp +++ b/src/MeoAssistant/ProcessTask.cpp @@ -33,7 +33,7 @@ asst::ProcessTask::ProcessTask(AbstractTask&& abs, std::vector task bool asst::ProcessTask::run() { if (!m_enable) { - Log.info("task is disable, pass", basic_info().to_string()); + Log.info("task disabled, pass", basic_info().to_string()); return true; } if (m_task_delay == TaskDelayUnsetted) { diff --git a/src/MeoAssistant/TaskData.cpp b/src/MeoAssistant/TaskData.cpp index d6ebabc49b..aa46fe6ae0 100644 --- a/src/MeoAssistant/TaskData.cpp +++ b/src/MeoAssistant/TaskData.cpp @@ -9,7 +9,7 @@ #include "TemplResource.h" #include "Logger.hpp" -const std::shared_ptr asst::TaskData::get(const std::string& name) const noexcept +std::shared_ptr asst::TaskData::get(const std::string& name) const noexcept { if (auto iter = m_all_tasks_info.find(name); iter != m_all_tasks_info.cend()) { @@ -35,7 +35,7 @@ bool asst::TaskData::parse(const json::value& json) LogTraceFunction; auto to_lower = [](char c) -> char { - return (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; + return char(std::tolower(c)); }; for (const auto& [name, task_json] : json.as_object()) { std::string algorithm_str = task_json.get("algorithm", "matchtemplate"); diff --git a/src/MeoAssistant/TaskData.h b/src/MeoAssistant/TaskData.h index adbe5d0259..590c1075d0 100644 --- a/src/MeoAssistant/TaskData.h +++ b/src/MeoAssistant/TaskData.h @@ -18,14 +18,14 @@ namespace asst virtual ~TaskData() = default; - static TaskData& get_instance() + static TaskData& get_instance() noexcept { static TaskData unique_instance; return unique_instance; } const std::unordered_set& get_templ_required() const noexcept; - const std::shared_ptr get(const std::string& name) const noexcept; + std::shared_ptr get(const std::string& name) const noexcept; std::shared_ptr get(const std::string& name); protected: