初步完成制造站换班的demo

This commit is contained in:
MistEO
2021-08-12 00:46:38 +08:00
parent f399144fe8
commit 3dfdb5be73
23 changed files with 450 additions and 242 deletions

View File

@@ -0,0 +1,66 @@
#include "InfrastConfiger.h"
#include <fstream>
#include <sstream>
#include <json.h>
#include "Logger.hpp"
using namespace asst;
bool InfrastConfiger::load(const std::string& filename)
{
DebugTraceFunction;
DebugTrace("Configer::load | ", filename);
InfrastConfiger temp;
if (temp._load(filename)) {
*this = std::move(temp);
return true;
}
else {
return false;
}
}
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;
}
json::value root = ret.value();
try {
// ÖÆÔìÕ¾
for (json::value& comb_info : root["Manufacturing"]["combs"].as_array())
{
std::vector<std::string> comb_vec;
for (json::value& oper_name : comb_info["comb"].as_array())
{
std::string oper_name_str = oper_name.as_string();
m_mfg_opers.emplace(oper_name_str);
comb_vec.emplace_back(std::move(oper_name_str));
}
m_mfg_combs.emplace_back(std::move(comb_vec));
}
// óÒ×Õ¾ TODO¡­¡­
}
catch (json::exception& e) {
DebugTraceError("Load config json error!", e.what());
return false;
}
DebugTrace("Load config succeed");
return true;
}

View File

@@ -26,25 +26,28 @@
<ClInclude Include="include\AsstPort.h" />
<ClInclude Include="include\Configer.h" />
<ClInclude Include="include\Identify.h" />
<ClInclude Include="include\InfrastConfiger.h" />
<ClInclude Include="include\Logger.hpp" />
<ClInclude Include="include\OpenRecruitConfiger.h" />
<ClInclude Include="include\RecruitConfiger.h" />
<ClInclude Include="include\Task.h" />
<ClInclude Include="include\Updater.h" />
<ClInclude Include="include\Version.h" />
<ClInclude Include="include\WinMacro.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="InfrastConfiger.cpp" />
<ClCompile Include="src\Assistance.cpp" />
<ClCompile Include="src\AsstCaller.cpp" />
<ClCompile Include="src\Configer.cpp" />
<ClCompile Include="src\Identify.cpp" />
<ClCompile Include="src\OpenRecruitConfiger.cpp" />
<ClCompile Include="src\RecruitConfiger.cpp" />
<ClCompile Include="src\Task.cpp" />
<ClCompile Include="src\Updater.cpp" />
<ClCompile Include="src\WinMacro.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\resource\operInfo.json" />
<None Include="..\resource\infrast.json" />
<None Include="..\resource\recruit.json" />
<None Include="..\resource\config.json" />
</ItemGroup>
<PropertyGroup Label="Globals">
@@ -155,7 +158,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;CSHARP_API;MEO_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;MEO_DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>
@@ -196,7 +199,7 @@ xcopy /e /y /i $(SolutionDir)3rdPart\resource $(TargetDir)resource</Command>
</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;CSHARP_API;MEO_DLL_EXPORTS;LOG_TRACE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;MEO_DLL_EXPORTS;LOG_TRACE;DEBUG_API;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>

View File

@@ -13,20 +13,23 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="头文件\configer">
<UniqueIdentifier>{07a812fe-6b28-4be0-b6d4-33554824d3c5}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\configer">
<UniqueIdentifier>{74bd94e1-4973-412a-a17a-d8457de387af}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\type">
<UniqueIdentifier>{87c9dee5-847b-41e6-818e-387a6385ea8b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\Configer.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\Identify.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\WinMacro.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\AsstDef.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\Assistance.h">
<Filter>头文件</Filter>
</ClInclude>
@@ -36,32 +39,35 @@
<ClInclude Include="include\Updater.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\Logger.hpp">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\AsstAux.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\AsstPort.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\OpenRecruitConfiger.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\Version.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\Task.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="include\InfrastConfiger.h">
<Filter>头文件\configer</Filter>
</ClInclude>
<ClInclude Include="include\RecruitConfiger.h">
<Filter>头文件\configer</Filter>
</ClInclude>
<ClInclude Include="include\Configer.h">
<Filter>头文件\configer</Filter>
</ClInclude>
<ClInclude Include="include\AsstDef.h">
<Filter>头文件\type</Filter>
</ClInclude>
<ClInclude Include="include\AsstAux.h">
<Filter>头文件\type</Filter>
</ClInclude>
<ClInclude Include="include\AsstPort.h">
<Filter>头文件\type</Filter>
</ClInclude>
<ClInclude Include="include\Version.h">
<Filter>头文件\type</Filter>
</ClInclude>
<ClInclude Include="include\Logger.hpp">
<Filter>头文件\type</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Configer.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\Identify.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\WinMacro.cpp">
<Filter>源文件</Filter>
</ClCompile>
@@ -74,18 +80,30 @@
<ClCompile Include="src\Updater.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\OpenRecruitConfiger.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\Task.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="InfrastConfiger.cpp">
<Filter>源文件\configer</Filter>
</ClCompile>
<ClCompile Include="src\Identify.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\RecruitConfiger.cpp">
<Filter>源文件\configer</Filter>
</ClCompile>
<ClCompile Include="src\Configer.cpp">
<Filter>源文件\configer</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resource\config.json">
<Filter>资源文件</Filter>
</None>
<None Include="..\resource\operInfo.json">
<None Include="..\resource\recruit.json">
<Filter>资源文件</Filter>
</None>
<None Include="..\resource\infrast.json">
<Filter>资源文件</Filter>
</None>
</ItemGroup>

View File

@@ -43,6 +43,9 @@ namespace asst {
bool set_param(const std::string& type, const std::string& param, const std::string& value);
// 滑动操作,调试用
bool swipe(const Point& p1, const Point& p2);
static constexpr int ProcessTaskRetryTimesDefault = 20;
static constexpr int OpenRecruitTaskRetyrTimesDefault = 5;

View File

@@ -22,6 +22,7 @@ extern "C" {
MEOAPI_PORT bool CheckVersionUpdate(char* tag_buffer, int tag_bufsize, char* html_url_buffer, int html_bufsize, char* body_buffer, int body_bufsize);
MEOAPI_PORT bool AsstTestSwipe(asst::Assistance* p_asst, int x1, int y1, int x2, int y2);
#ifdef __cplusplus
}
#endif

View File

@@ -103,6 +103,7 @@ namespace asst {
std::string path;
std::string connect;
std::string click;
std::string swipe;
std::string display;
std::string display_regex;
int display_width = 0;

View File

@@ -2,7 +2,6 @@
#include <string>
#include <unordered_map>
#include <optional>
#include <memory>
#include "AsstDef.h"
@@ -22,9 +21,6 @@ namespace asst {
bool set_param(const std::string& type, const std::string& param, const std::string& value);
Configer& operator=(const Configer& rhs) = default;
Configer& operator=(Configer&& rhs) noexcept = default;
constexpr static int DefaultWindowWidth = 1280;
constexpr static int DefaultWindowHeight = 720;
constexpr static double Defaulttempl_threshold = 0.9;
@@ -42,6 +38,9 @@ namespace asst {
Configer(const Configer& rhs) = default;
Configer(Configer&& rhs) noexcept = default;
Configer& operator=(const Configer& rhs) = default;
Configer& operator=(Configer && rhs) noexcept = default;
bool _load(const std::string& filename);
};
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <string>
#include <unordered_map>
#include <unordered_set>
#include "AsstDef.h"
namespace asst {
class InfrastConfiger
{
public:
~InfrastConfiger() = default;
static InfrastConfiger& get_instance() {
static InfrastConfiger unique_instance;
return unique_instance;
}
bool load(const std::string& filename);
std::vector<std::vector<std::string>> m_mfg_combs; // 制造站组合
std::unordered_set<std::string> m_mfg_opers; // 制造站所有干员
private:
InfrastConfiger() = default;
InfrastConfiger(const InfrastConfiger& rhs) = default;
InfrastConfiger(InfrastConfiger&& rhs) noexcept = default;
InfrastConfiger& operator=(const InfrastConfiger& rhs) = default;
InfrastConfiger& operator=(InfrastConfiger && rhs) noexcept = default;
bool _load(const std::string& filename);
};
}

View File

@@ -1,39 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_set>
#include "AsstDef.h"
namespace asst {
class OpenRecruitConfiger
{
public:
~OpenRecruitConfiger() = default;
static OpenRecruitConfiger& get_instance() {
static OpenRecruitConfiger unique_instance;
return unique_instance;
}
bool load(const std::string& filename);
OpenRecruitConfiger& operator=(const OpenRecruitConfiger& rhs) = default;
OpenRecruitConfiger& operator=(OpenRecruitConfiger&& rhs) noexcept = default;
std::unordered_set<std::string> m_all_tags;
std::unordered_set<std::string> m_all_types;
std::vector<OperInfo> m_all_opers;
constexpr static int CorrectNumberOfTags = 5;
private:
OpenRecruitConfiger() = default;
OpenRecruitConfiger(const OpenRecruitConfiger& rhs) = default;
OpenRecruitConfiger(OpenRecruitConfiger&& rhs) noexcept = default;
bool _load(const std::string& filename);
};
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_set>
#include "AsstDef.h"
namespace asst {
class RecruitConfiger
{
public:
~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;
std::vector<OperInfo> m_all_opers;
constexpr static int CorrectNumberOfTags = 5;
private:
RecruitConfiger() = default;
RecruitConfiger(const RecruitConfiger& rhs) = default;
RecruitConfiger(RecruitConfiger&& rhs) noexcept = default;
RecruitConfiger& operator=(const RecruitConfiger& rhs) = default;
RecruitConfiger& operator=(RecruitConfiger && rhs) noexcept = default;
bool _load(const std::string& filename);
};
}

View File

@@ -25,7 +25,7 @@ namespace asst {
class WinMacro;
class Identify;
class Configer;
class OpenRecruitConfiger;
class RecruitConfiger;
enum TaskType {
TaskTypeInvalid = 0,

View File

@@ -25,6 +25,8 @@ namespace asst {
bool hideWindow();
bool click(const Point& p);
bool click(const Rect& rect);
bool swipe(const Point& p1, const Point& p2);
bool swipe(const Rect& r1, const Rect& r2);
void setControlScale(double scale);
cv::Mat getImage(const Rect& rect);
Rect getWindowRect();
@@ -35,12 +37,14 @@ namespace asst {
private:
bool findHandle();
std::optional<std::string> callCmd(const std::string& cmd, bool use_pipe = true);
Point randPointInRect(const Rect& rect);
const EmulatorInfo m_emulator_info;
const HandleType m_handle_type;
HWND m_handle = NULL;
bool m_is_adb = false;
std::string m_click_cmd; // adb点击命令不是adb的句柄用不到这个
std::string m_swipe_cmd; // adb滑动命令不是adb的句柄用不到这个
std::minstd_rand m_rand_engine;
int m_width = 0;
int m_height = 0;

View File

@@ -6,7 +6,8 @@
#include "Logger.hpp"
#include "AsstAux.h"
#include "Task.h"
#include "OpenRecruitConfiger.h"
#include "RecruitConfiger.h"
#include "InfrastConfiger.h"
#include <json.h>
#include <opencv2/opencv.hpp>
@@ -33,7 +34,12 @@ Assistance::Assistance(AsstCallback callback, void* callback_arg)
callback_error();
return;
}
ret = OpenRecruitConfiger::get_instance().load(GetResourceDir() + "operInfo.json");
ret = RecruitConfiger::get_instance().load(GetResourceDir() + "recruit.json");
if (!ret) {
callback_error();
return;
}
ret = InfrastConfiger::get_instance().load(GetResourceDir() + "infrast.json");
if (!ret) {
callback_error();
return;
@@ -234,6 +240,11 @@ bool Assistance::set_param(const std::string& type, const std::string& param, co
return Configer::get_instance().set_param(type, param, value);
}
bool asst::Assistance::swipe(const Point& p1, const Point& p2)
{
return m_control_ptr->swipe(p1, p2);
}
void Assistance::working_proc(Assistance* p_this)
{
DebugTraceFunction;

View File

@@ -139,4 +139,12 @@ bool CheckVersionUpdate(char* tag_buffer, int tag_bufsize, char* html_url_buffer
strcpy_s(html_url_buffer, html_bufsize, info.html_url.c_str());
strcpy_s(body_buffer, body_bufsize, info.body.c_str());
return true;
}
}
bool AsstTestSwipe(asst::Assistance* p_asst, int x1, int y1, int x2, int y2)
{
if (p_asst == NULL) {
return false;
}
return p_asst->swipe({ x1, y1 }, { x2, y2 });
}

View File

@@ -250,10 +250,10 @@ bool asst::Configer::_load(const std::string& filename)
}
if (emulator_json.exist("adb")) {
emulator_info.is_adb = true;
std::cout << emulator_json.to_string() << std::endl;
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();
}

View File

@@ -1,4 +1,4 @@
#include "OpenRecruitConfiger.h"
#include "RecruitConfiger.h"
#include <fstream>
#include <sstream>
@@ -9,12 +9,12 @@
using namespace asst;
bool OpenRecruitConfiger::load(const std::string& filename)
bool RecruitConfiger::load(const std::string& filename)
{
DebugTraceFunction;
DebugTrace("OpenRecruitConfiger::load | ", filename);
DebugTrace("RecruitConfiger::load | ", filename);
OpenRecruitConfiger temp;
RecruitConfiger temp;
if (temp._load(filename)) {
// 按干员等级排个序
std::sort(temp.m_all_opers.begin(), temp.m_all_opers.end(), [](
@@ -31,7 +31,7 @@ bool OpenRecruitConfiger::load(const std::string& filename)
}
}
bool asst::OpenRecruitConfiger::_load(const std::string& filename)
bool asst::RecruitConfiger::_load(const std::string& filename)
{
std::ifstream ifs(filename, std::ios::in);
if (!ifs.is_open()) {

View File

@@ -3,7 +3,8 @@
#include "WinMacro.h"
#include "Identify.h"
#include "Configer.h"
#include "OpenRecruitConfiger.h"
#include "RecruitConfiger.h"
#include "InfrastConfiger.h"
#include <json.h>
#include "AsstAux.h"
@@ -13,6 +14,7 @@
#include <cmath>
#include <mutex>
#include <filesystem>
#include <future>
using namespace asst;
@@ -428,7 +430,7 @@ bool OpenRecruitTask::run()
/* Filter out all tags from all text */
std::vector<TextArea> all_tags = text_match(
all_text_area, OpenRecruitConfiger::get_instance().m_all_tags, Configer::get_instance().m_recruit_ocr_replace);
all_text_area, RecruitConfiger::get_instance().m_all_tags, Configer::get_instance().m_recruit_ocr_replace);
std::unordered_set<std::string> all_tags_name;
std::vector<json::value> all_tags_json_vector;
@@ -441,7 +443,7 @@ bool OpenRecruitTask::run()
m_callback(AsstMsg::RecruitTagsDetected, all_tags_json, m_callback_arg);
/* 过滤tags数量不足的情况可能是识别漏了 */
if (all_tags.size() != OpenRecruitConfiger::CorrectNumberOfTags) {
if (all_tags.size() != RecruitConfiger::CorrectNumberOfTags) {
all_tags_json["type"] = "OpenRecruit";
m_callback(AsstMsg::OcrResultError, all_tags_json, m_callback_arg);
return false;
@@ -488,7 +490,7 @@ bool OpenRecruitTask::run()
// 例如 key: { "狙击"、"群攻" }value: OperCombs.opers{ "陨星", "白雪", "空爆" }
std::map<std::vector<std::string>, OperCombs> result_map;
for (const std::vector<std::string>& comb : all_combs) {
for (const OperInfo& cur_oper : OpenRecruitConfiger::get_instance().m_all_opers) {
for (const OperInfo& cur_oper : RecruitConfiger::get_instance().m_all_opers) {
int matched_count = 0;
for (const std::string& tag : comb) {
if (cur_oper.tags.find(tag) != cur_oper.tags.cend()) {
@@ -659,39 +661,105 @@ bool TestOcrTask::run()
};
m_callback(AsstMsg::TaskStart, task_start_json, m_callback_arg);
/* Find all text */
std::vector<TextArea> all_text_area = ocr_detect();
auto swipe_foo = [&](bool reverse = false) -> bool {
const Point p1(600, 300);
const Point p2(500, 300);
bool ret = false;
if (!reverse) {
m_control_ptr->swipe(p1, p2);
}
else {
m_control_ptr->swipe(p2, p1);
}
sleep(3000);
return ret;
};
std::vector<json::value> all_text_json_vector;
for (const TextArea& text_area : all_text_area) {
all_text_json_vector.emplace_back(Utf8ToGbk(text_area.text));
// 识别到的干员名
std::unordered_set<std::string> all_opers;
// 一边识别一边滑动,把所有制造站干员名字抓出来
for (int i = 0; i != 10; ++i) {
const cv::Mat& image = get_format_image();
// 异步进行滑动操作
std::future<bool> swipe_future = std::async(std::launch::async, swipe_foo);
std::vector<TextArea> all_text_area = ocr_detect(image);
/* 过滤出所有制造站中的干员名 */
std::vector<TextArea> cur_opers = text_search(
all_text_area,
InfrastConfiger::get_instance().m_mfg_opers,
Configer::get_instance().m_infrast_ocr_replace);
for (TextArea& text_area : cur_opers) {
all_opers.emplace(std::move(text_area.text));
}
swipe_future.get();
}
json::value all_text_json;
all_text_json["text"] = json::array(all_text_json_vector);
m_callback(AsstMsg::TextDetected, all_text_json, m_callback_arg);
/* Filter out all text from all text */
std::vector<TextArea> all_text = text_search(
all_text_area, m_text_vec, Configer::get_instance().m_infrast_ocr_replace);
std::vector<json::value> all_tags_json_vector;
for (const TextArea& text_area : all_text) {
all_tags_json_vector.emplace_back(Utf8ToGbk(text_area.text));
std::cout << "识别到制造站干员:" << std::endl;
for (const std::string& oper : all_opers) {
std::cout << Utf8ToGbk(oper) << std::endl;
}
json::value all_tags_json;
all_tags_json["tags"] = json::array(all_tags_json_vector);
m_callback(AsstMsg::RecruitTagsDetected, all_tags_json, m_callback_arg);
// 点击识别到的文字,直接回调扔出去,交给外层做
if (m_need_click) {
for (const TextArea& text_area : all_text) {
json::value task_json;
task_json["type"] = "ClickTask";
task_json["rect"] = json::array({ text_area.rect.x, text_area.rect.y, text_area.rect.width, text_area.rect.height });
task_json["retry_times"] = m_retry_times;
task_json["task_chain"] = m_task_chain;
m_callback(AsstMsg::AppendTask, task_json, m_callback_arg);
// 配置文件中的干员组合,和抓出来的干员名比对,如果组合中的干员都有,那就用这个组合
// Todo 时间复杂度起飞了,需要优化下
std::vector<std::string> optimal_comb;
for (auto&& oper_vec : InfrastConfiger::get_instance().m_mfg_combs) {
int count = 0;
for (std::string& oper : oper_vec) {
if (all_opers.find(oper) != all_opers.cend()) {
++count;
}
else {
break;
}
}
if (count == oper_vec.size()) {
optimal_comb = oper_vec;
break;
}
}
std::cout << "最优组合:" << std::endl;
for (const std::string& oper : optimal_comb) {
std::cout << Utf8ToGbk(oper) << std::endl;
}
// 一边滑动一边点击最优解中的干员
for (int i = 0; i != 20; ++i) {
const cv::Mat& image = get_format_image();
std::vector<TextArea> all_text_area = ocr_detect(image);
/* 过滤出所有制造站中的干员名 */
std::vector<TextArea> cur_opers = text_search(
all_text_area,
optimal_comb,
Configer::get_instance().m_infrast_ocr_replace);
for (TextArea& text_area : cur_opers) {
m_control_ptr->click(text_area.rect);
// 点过了就不会再点了直接从最优解vector里面删了
optimal_comb.erase(std::find(optimal_comb.begin(), optimal_comb.end(), text_area.text));
}
if (optimal_comb.empty()) {
break;
}
// 因为滑动和点击是矛盾的,这里没法异步做
swipe_foo(true);
}
//// 点击识别到的文字,直接回调扔出去,交给外层做
//if (m_need_click) {
// for (const TextArea& text_area : all_text) {
// json::value task_json;
// task_json["type"] = "ClickTask";
// task_json["rect"] = json::array({ text_area.rect.x, text_area.rect.y, text_area.rect.width, text_area.rect.height });
// task_json["retry_times"] = m_retry_times;
// task_json["task_chain"] = m_task_chain;
// m_callback(AsstMsg::AppendTask, task_json, m_callback_arg);
// }
//}
return true;
}

View File

@@ -114,6 +114,7 @@ bool WinMacro::findHandle()
}
m_click_cmd = adb_dir + m_emulator_info.adb.click;
m_swipe_cmd = adb_dir + m_emulator_info.adb.swipe;
}
DebugTrace("Handle:", m_handle, "Name:", m_emulator_info.name, "Type:", m_handle_type);
@@ -190,6 +191,29 @@ std::optional<std::string> asst::WinMacro::callCmd(const std::string& cmd, bool
return pipe_str;
}
Point asst::WinMacro::randPointInRect(const Rect& rect)
{
int x = 0, y = 0;
if (rect.width == 0) {
x = rect.x;
}
else {
int x_rand = std::poisson_distribution<int>(rect.width / 2)(m_rand_engine);
x = x_rand + rect.x;
}
if (rect.height == 0) {
y = rect.y;
}
else {
int y_rand = std::poisson_distribution<int>(rect.height / 2)(m_rand_engine);
y = y_rand + rect.y;
}
return Point(x, y);
}
bool WinMacro::resizeWindow(int width, int height)
{
if (m_handle_type != HandleType::Window || !::IsWindow(m_handle)) {
@@ -289,25 +313,41 @@ bool WinMacro::click(const Rect& rect)
return false;
}
int x = 0, y = 0;
if (rect.width == 0) {
x = rect.x;
}
else {
int x_rand = std::poisson_distribution<int>(rect.width / 2)(m_rand_engine);
return click(randPointInRect(rect));
}
x = x_rand + rect.x;
bool asst::WinMacro::swipe(const Point& p1, const Point& p2)
{
if (m_handle_type != HandleType::Control || !::IsWindow(m_handle)) {
return false;
}
if (rect.height == 0) {
y = rect.y;
int x1 = p1.x * m_control_scale;
int y1 = p1.y * m_control_scale;
int x2 = p2.x * m_control_scale;
int y2 = p2.y * m_control_scale;
DebugTrace("Swipe, raw:", p1.x, p1.y, p2.x, p2.y, "corr:", x1, y1, x2, y2);
if (m_is_adb) {
std::string cur_cmd = StringReplaceAll(m_swipe_cmd, "[x1]", std::to_string(x1));
cur_cmd = StringReplaceAll(cur_cmd, "[y1]", std::to_string(y1));
cur_cmd = StringReplaceAll(cur_cmd, "[x2]", std::to_string(x2));
cur_cmd = StringReplaceAll(cur_cmd, "[y2]", std::to_string(y2));
return callCmd(cur_cmd, false).has_value();
return true;
}
else {
int y_rand = std::poisson_distribution<int>(rect.height / 2)(m_rand_engine);
y = y_rand + rect.y;
else { // TODO
return false;
}
}
bool asst::WinMacro::swipe(const Rect& r1, const Rect& r2)
{
if (m_handle_type != HandleType::Control || !::IsWindow(m_handle)) {
return false;
}
return click({ x, y });
return swipe(randPointInRect(r1), randPointInRect(r2));
}
void asst::WinMacro::setControlScale(double scale)

View File

@@ -123,7 +123,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(SolutionDir)meojson\include;$(SolutionDir)MeoAssistance\include;$(IncludePath)</IncludePath>
<IncludePath>$(SolutionDir)MeoAssistance\include;$(IncludePath)</IncludePath>
<LibraryPath>$(TargetDir);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">

View File

@@ -1,9 +1,13 @@
#include "AsstCaller.h"
#include <stdio.h>
using namespace asst;
void test_dorm(Assistance* ptr);
void test_swipe(Assistance* ptr);
int main(int argc, char** argv)
{
using namespace asst;
Assistance* ptr = AsstCreate();
auto ret = AsstCatchEmulator(ptr);
@@ -15,11 +19,13 @@ int main(int argc, char** argv)
}
return -1;
}
const char* text_array[] = { "×¢ÒâÁ¦" };
char ch = 0;
while (ch != 'q') {
AsstTestOcr(ptr, text_array, sizeof(text_array) / sizeof(char*), true);
test_dorm(ptr);
//test_swipe(ptr);
ch = getchar();
}
@@ -29,4 +35,16 @@ int main(int argc, char** argv)
}
return 0;
}
void test_swipe(Assistance* ptr)
{
AsstTestSwipe(ptr, 1000, 300, 500, 300);
}
void test_dorm(Assistance* ptr)
{
const char* text_array[] = { "×¢ÒâÁ¦" };
AsstTestOcr(ptr, text_array, sizeof(text_array) / sizeof(char*), true);
}

View File

@@ -30,6 +30,8 @@
[ "都任", "输出" ]
],
"infrastOcrReplace": [
[ "森蛐", "森蚺" ],
[ "森蛾", "森蚺" ]
],
"handle_Doc": "下面的和模拟器窗口捕获逻辑有关,不需要修改",
"handle": {
@@ -60,115 +62,19 @@
"window": "BlueStacks Android PluginAndroid"
}
],
"adb": {
"path": "[EmulatorPath]HD-Adb.exe",
"connect": " connect 127.0.0.1:5555",
"click": " -s 127.0.0.1:5555 shell input tap [x] [y]",
"swipe": " -s 127.0.0.1:5555 shell input swipe [x1] [y1] [x2] [y2]",
"display": " -s 127.0.0.1:5555 shell dumpsys window displays | grep init= | awk ' { print $3 } '",
"displayRegex": "cur=%dx%d"
},
"xOffset": 11,
"yOffset": 46,
"rightOffset": 11,
"bottomOffset": 10
},
"Nox": {
"window": [
{
"class": "Qt5QWindowIcon",
"window": "夜神模拟器"
}
],
"view": [
{
"class": "Qt5QWindowIcon",
"window": "夜神模拟器"
}
],
"control": [
{
"class": "Qt5QWindowIcon",
"window": "夜神模拟器"
}
],
"xOffset": 2,
"yOffset": 39,
"rightOffset": 39,
"bottomOffset": 9
},
"LDPlayer": {
"window": [
{
"class": "LDPlayerMainFrame",
"window": "雷电模拟器"
}
],
"view": [
{
"class": "LDPlayerMainFrame",
"window": "雷电模拟器"
}
],
"control": [
{
"class": "LDPlayerMainFrame",
"window": "雷电模拟器"
},
{
"class": "RenderWindow",
"window": "TheRender"
}
],
"xOffset": 0,
"yOffset": 35
},
"XYAZ": {
"window": [
{
"class": "Qt5QWindowIcon",
"window": "逍遥模拟器"
}
],
"view": [
{
"class": "Qt5QWindowIcon",
"window": "逍遥模拟器"
}
],
"control": [
{
"class": "Qt5QWindowIcon",
"window": "逍遥模拟器"
},
{
"class": "Qt5QWindowIcon",
"window": "MainWindowWindow"
}
],
"xOffset": 1,
"yOffset": 48,
"rightOffset": 1,
"bottomOffset": 1
},
"Tencent": {
"window": [
{
"class": "TXGuiFoundation",
"window": "腾讯手游助手"
}
],
"view": [
{
"class": "TXGuiFoundation",
"window": "腾讯手游助手"
}
],
"control": [
{
"class": "TXGuiFoundation",
"window": "腾讯手游助手"
},
{
"class": "AEngineRenderWindowClass",
"window": "AEngineRenderWindow"
}
],
"xOffset": 1,
"yOffset": 42
},
"MuMuEmulator": {
"window": [
{
@@ -191,8 +97,9 @@
"adb": {
"path": "[EmulatorPath]..\\\\vmonitor\\\\bin\\\\adb_server.exe",
"connect": " connect 127.0.0.1:7555",
"click": " shell input tap [x] [y]",
"display": " shell dumpsys window displays | grep init= | awk ' { print $3 } '",
"click": " -s 127.0.0.1:7555 shell input tap [x] [y]",
"swipe": " -s 127.0.0.1:7555 shell input swipe [x1] [y1] [x2] [y2]",
"display": " -s 127.0.0.1:7555 shell dumpsys window displays | grep init= | awk ' { print $3 } '",
"displayRegex": "cur=%dx%d"
},
"xOffset": 0,

26
resource/infrast.json Normal file
View File

@@ -0,0 +1,26 @@
{
"Manufacturing": {
"Doc": "制造站",
"combs": [
{
"comb": [
"刻俄柏",
"稀音",
"红云"
],
"efficiency": 105
},
{
"comb": [
"温蒂",
"异客",
"森蚺"
],
"efficiency": 90
}
]
},
"Trade": {
"Doc": "贸易站"
}
}