diff --git a/MeoAssistance/MeoAssistance.vcxproj b/MeoAssistance/MeoAssistance.vcxproj index 41b030bd05..6dfa024cb6 100644 --- a/MeoAssistance/MeoAssistance.vcxproj +++ b/MeoAssistance/MeoAssistance.vcxproj @@ -19,7 +19,7 @@ - + diff --git a/MeoAssistance/MeoAssistance.vcxproj.filters b/MeoAssistance/MeoAssistance.vcxproj.filters index a5553f6a13..6959fca90b 100644 --- a/MeoAssistance/MeoAssistance.vcxproj.filters +++ b/MeoAssistance/MeoAssistance.vcxproj.filters @@ -15,9 +15,6 @@ - - 头文件 - 头文件 @@ -30,6 +27,9 @@ 头文件 + + 头文件 + diff --git a/MeoAssistance/include/Assistance.h b/MeoAssistance/include/Assistance.h index ed32bff6fd..aecda81c96 100644 --- a/MeoAssistance/include/Assistance.h +++ b/MeoAssistance/include/Assistance.h @@ -6,9 +6,9 @@ #include #include -#include "AssDef.h" +#include "AsstDef.h" -namespace MeoAssistance { +namespace asst { class WinMacro; class Identify; @@ -24,25 +24,18 @@ namespace MeoAssistance { void stop(); private: - static void identify_function(Assistance* pThis); // ʶ̣߳ - static void control_function(Assistance* pThis); // ̣߳ + static void working_proc(Assistance* pThis); std::shared_ptr m_pCtrl = nullptr; std::shared_ptr m_pWindow = nullptr; std::shared_ptr m_pView = nullptr; std::shared_ptr m_Ider = nullptr; - std::queue m_tasks; - std::mutex m_tasks_mutex; - - std::thread m_control_thread; - std::thread m_identify_thread; - bool m_control_exit = false; - bool m_identify_exit = false; - bool m_control_running = false; - bool m_identify_running = false; - std::condition_variable m_control_cv; - std::condition_variable m_identify_cv; + std::thread m_working_thread; + std::mutex m_mutex; + std::condition_variable m_condvar; + bool m_thread_exit = false; + bool m_thread_running = false; }; } \ No newline at end of file diff --git a/MeoAssistance/include/AssDef.h b/MeoAssistance/include/AsstDef.h similarity index 75% rename from MeoAssistance/include/AssDef.h rename to MeoAssistance/include/AsstDef.h index 8ddf7be58c..19af9d4ab3 100644 --- a/MeoAssistance/include/AssDef.h +++ b/MeoAssistance/include/AsstDef.h @@ -7,7 +7,7 @@ #include #include -namespace MeoAssistance { +namespace asst { enum class SimulatorType { BlueStacks = 0x100 @@ -25,6 +25,7 @@ namespace MeoAssistance { struct Point { + Point() = default; Point(int x, int y) : x(x), y(y) {} int x = 0; int y = 0; @@ -32,9 +33,19 @@ namespace MeoAssistance { struct Rect { + Rect() = default; Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} - Rect operator*(double rhs) const { return { x, y, static_cast(width * rhs), static_cast(height * rhs) }; } + Rect operator*(double rhs) const + { + return { x, y, static_cast(width * rhs), static_cast(height * rhs) }; + } + Rect center_zoom(double scale) + { + int half_width_scale = static_cast(width * (1- scale) / 2) ; + int half_hight_scale = static_cast(height * (1 - scale) / 2) ; + return { x + half_width_scale, y + half_hight_scale, width - half_width_scale, height - half_hight_scale }; + } int x = 0; int y = 0; int width = 0; @@ -50,7 +61,7 @@ namespace MeoAssistance { } template - void DebugPrint(const std::string & level, Args &&... args) + void DebugPrint(const std::string& level, Args &&... args) { static std::mutex trace_mutex; std::unique_lock trace_lock(trace_mutex); diff --git a/MeoAssistance/include/Configer.h b/MeoAssistance/include/Configer.h index 730ed6139f..9070c54572 100644 --- a/MeoAssistance/include/Configer.h +++ b/MeoAssistance/include/Configer.h @@ -3,7 +3,7 @@ #include #include "json_object.h" -namespace MeoAssistance { +namespace asst { class Configer { public: @@ -14,7 +14,7 @@ namespace MeoAssistance { static std::string getResDir(); static json::object dataObj; static json::object handleObj; - + static json::object optionsObj; private: Configer() = default; diff --git a/MeoAssistance/include/Identify.h b/MeoAssistance/include/Identify.h index 91f384c6b2..fb6d3777b6 100644 --- a/MeoAssistance/include/Identify.h +++ b/MeoAssistance/include/Identify.h @@ -1,11 +1,12 @@ #pragma once -#include "AssDef.h" +#include "AsstDef.h" #include #include +#include -namespace MeoAssistance { +namespace asst { class WinMacro; @@ -14,9 +15,15 @@ namespace MeoAssistance { public: Identify() = default; ~Identify() = default; - double imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs); - double imgHistComp(const cv::Mat& cur, const std::string& src, MeoAssistance::Rect compRect); + bool addImage(const std::string& name, const std::string& path); + + double imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs); + double imgHistComp(const cv::Mat& cur, const std::string& src, asst::Rect compRect); + std::pair findImage(const cv::Mat& image, const cv::Mat& templ); + std::pair findImage(const cv::Mat& cur, const std::string& templ); + std::pair findImageWithFile(const cv::Mat& cur, const std::string& filename); + private: std::unordered_map m_matMap; }; diff --git a/MeoAssistance/include/WinMacro.h b/MeoAssistance/include/WinMacro.h index 964d4cae24..f87fca9392 100644 --- a/MeoAssistance/include/WinMacro.h +++ b/MeoAssistance/include/WinMacro.h @@ -5,9 +5,9 @@ #include #include -#include "AssDef.h" +#include "AsstDef.h" -namespace MeoAssistance { +namespace asst { class WinMacro { public: @@ -16,6 +16,7 @@ namespace MeoAssistance { bool findHandle(); bool resizeWindow(int Width, int Height); + bool resizeWindow(); // by configer bool click(const Point & p); bool clickRange(const Rect & rect); cv::Mat getImage(const Rect& rect); @@ -26,5 +27,9 @@ namespace MeoAssistance { HandleType m_handle_type; HWND m_handle = NULL; std::minstd_rand m_rand_engine; + int m_width = 0; + int m_height = 0; + int m_xOffset = 0; + int m_yOffset = 0; }; } diff --git a/MeoAssistance/src/Assistance.cpp b/MeoAssistance/src/Assistance.cpp index a41acc9b26..56a9e89862 100644 --- a/MeoAssistance/src/Assistance.cpp +++ b/MeoAssistance/src/Assistance.cpp @@ -4,7 +4,7 @@ #include "Configer.h" #include "Identify.h" -using namespace MeoAssistance; +using namespace asst; Assistance::Assistance() { @@ -16,26 +16,18 @@ Assistance::Assistance() m_Ider->addImage(pair.first, Configer::getResDir() + pair.second["filename"].as_string()); } - m_control_thread = std::thread(control_function, this); - m_identify_thread = std::thread(identify_function, this); + m_working_thread = std::thread(working_proc, this); } Assistance::~Assistance() { - m_control_exit = true; - m_control_running = false; - m_control_cv.notify_all(); + m_thread_exit = true; + m_thread_running = false; + m_condvar.notify_one(); - m_identify_exit = true; - m_identify_running = false; - m_identify_cv.notify_all(); - - if (m_control_thread.joinable()) { - m_control_thread.join(); - } - if (m_identify_thread.joinable()) { - m_identify_thread.join(); + if (m_working_thread.joinable()) { + m_working_thread.join(); } } @@ -43,95 +35,104 @@ bool Assistance::setSimulatorType(SimulatorType type) { stop(); - std::unique_lock lock(m_tasks_mutex); - std::queue empty; - m_tasks.swap(empty); + std::unique_lock lock(m_mutex); int int_type = static_cast(type); m_pCtrl = std::make_shared(static_cast(int_type | static_cast(HandleType::Control))); m_pWindow = std::make_shared(static_cast(int_type | static_cast(HandleType::Window))); m_pView = std::make_shared(static_cast(int_type | static_cast(HandleType::View))); bool ret = m_pCtrl->findHandle() && m_pWindow->findHandle() && m_pView->findHandle(); if (ret) { - m_pWindow->resizeWindow(1200, 720); + ret = m_pWindow->resizeWindow(); } return ret; } void Assistance::start() { - std::unique_lock lock(m_tasks_mutex); + std::unique_lock lock(m_mutex); - m_control_running = true; - m_identify_running = true; - m_control_cv.notify_all(); - m_identify_cv.notify_all(); + m_thread_running = true; + m_condvar.notify_one(); } void Assistance::stop() { - std::unique_lock lock(m_tasks_mutex); + std::unique_lock lock(m_mutex); - m_control_running = false; - m_identify_running = false; + m_thread_running = false; } -void Assistance::identify_function(Assistance* pThis) +void Assistance::working_proc(Assistance* pThis) { - while (!pThis->m_identify_exit) { - std::unique_lock lock(pThis->m_tasks_mutex); - if (pThis->m_identify_running) { + while (!pThis->m_thread_exit) { + std::unique_lock lock(pThis->m_mutex); + if (pThis->m_thread_running) { auto curImg = pThis->m_pView->getImage(pThis->m_pView->getWindowRect()); - std::string matched_task; - double max_similarity = 0; + double max_value = -1; + Rect cor_rect; + std::pair matched; for (auto&& pair : Configer::dataObj) { - double similarity = pThis->m_Ider->imgHistComp(curImg, pair.first, jsonToRect(pair.second["viewRect"].as_array())); - DebugTrace("%-20s %f", pair.first.c_str(), similarity); - if (similarity >= pair.second["similarity"].as_double()) { - if (similarity > max_similarity) { - max_similarity = similarity; - matched_task = pair.first; + auto&& [value, rect] = pThis->m_Ider->findImage(curImg, pair.first); + DebugTrace("%-20s %f", pair.first.c_str(), value); + if (value >= pair.second["threshold"].as_double()) { + if (value >= max_value) { + max_value = value; + cor_rect = rect; + matched = pair; } } } - if (max_similarity != 0) { - DebugTrace("Max: %s, Similarity: %f", matched_task.c_str(), max_similarity); - pThis->m_tasks.emplace(matched_task); + if (max_value >= 0) { + auto task = Configer::dataObj[matched.first].as_object(); + std::string opType = task["type"].as_string(); + DebugTraceInfo("Matched: %s, type: %s", matched.first.c_str(), opType.c_str()); + bool next_loop = true; + while (next_loop) { + if (opType == "clickSelf") { + pThis->m_pCtrl->clickRange(cor_rect); + } + else if (opType == "clickRand") { + pThis->m_pCtrl->clickRange(pThis->m_pCtrl->getWindowRect()); + } + else if (opType == "next") { + json::value nextObj = task["next"]; + std::string name = nextObj["name"].as_string(); + std::string filepath = Configer::getResDir() + nextObj["filename"].as_string(); + auto&& [value, rect] = pThis->m_Ider->findImageWithFile(curImg, filepath); + DebugTrace("Next: %-20s %f", name.c_str(), value); - pThis->m_control_cv.notify_all(); + if (value >= nextObj["threshold"].as_double()) { + DebugTraceInfo("Next matched: %s", name.c_str()); + task = nextObj.as_object(); + opType = nextObj["type"].as_string(); + cor_rect = rect; + max_value = value; + next_loop = true; + continue; + } + else { + DebugTraceInfo("Next not matched: %s", name.c_str()); + } + } + else if (opType == "stop") { + DebugTrace("opType == stop"); + pThis->m_thread_running = false; + break; + } + else if (opType == "doNothing") { + // do nothing + } + else { + DebugTraceError("Unknow option type: %s", opType.c_str()); + } + next_loop = false; + } } - - pThis->m_identify_cv.wait_for(lock, std::chrono::milliseconds(1000)); + pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(Configer::optionsObj["delay"].as_integer())); } else { - pThis->m_identify_cv.wait(lock); - } - } -} - -void Assistance::control_function(Assistance* pThis) -{ - while (!pThis->m_control_exit) { - std::unique_lock lock(pThis->m_tasks_mutex); - if (pThis->m_control_running && !pThis->m_tasks.empty()) { - const std::string task_name = pThis->m_tasks.front(); - pThis->m_tasks.pop(); - lock.unlock(); - - auto task = Configer::dataObj[task_name].as_object(); - std::string opType = task["type"].as_string(); - if (opType == "click") { - pThis->m_pCtrl->clickRange(jsonToRect(task["ctrlRect"].as_array())); - } - else if (opType == "stop") { - DebugTrace("opType == stop"); - pThis->m_control_running = false; - pThis->m_identify_running = false; - continue; - } - } - else { - pThis->m_control_cv.wait(lock); + pThis->m_condvar.wait(lock); } } } \ No newline at end of file diff --git a/MeoAssistance/src/Configer.cpp b/MeoAssistance/src/Configer.cpp index c8df3ea6f1..c847f1aa55 100644 --- a/MeoAssistance/src/Configer.cpp +++ b/MeoAssistance/src/Configer.cpp @@ -6,10 +6,11 @@ #include "json.h" -using namespace MeoAssistance; +using namespace asst; json::object Configer::dataObj; json::object Configer::handleObj; +json::object Configer::optionsObj; std::string Configer::m_curDir; @@ -33,6 +34,8 @@ bool Configer::reload() auto root = std::move(ret).value(); dataObj = root["data"].as_object(); handleObj = root["handle"].as_object(); + optionsObj = root["options"].as_object(); + return true; } diff --git a/MeoAssistance/src/Identify.cpp b/MeoAssistance/src/Identify.cpp index cb67b91f93..5ec457971b 100644 --- a/MeoAssistance/src/Identify.cpp +++ b/MeoAssistance/src/Identify.cpp @@ -4,9 +4,19 @@ #include #include -using namespace MeoAssistance; +using namespace asst; using namespace cv; +bool Identify::addImage(const std::string& name, const std::string& path) +{ + Mat mat = imread(path); + if (mat.empty()) { + return false; + } + m_matMap.emplace(name, mat); + return true; +} + double Identify::imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs) { cv::Mat lhs_hsv; @@ -32,18 +42,45 @@ double Identify::imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs) return compareHist(lhs_hist, rhs_hist, CV_COMP_CORREL); } -double Identify::imgHistComp(const cv::Mat& cur, const std::string& src, MeoAssistance::Rect compRect) +double Identify::imgHistComp(const cv::Mat& cur, const std::string& src, asst::Rect compRect) { + if (m_matMap.find(src) == m_matMap.end()) { + return 0; + } cv::Rect cvRect(compRect.x, compRect.y, compRect.width, compRect.height); return imgHistComp(cur(cvRect), m_matMap.at(src)(cvRect)); } -bool Identify::addImage(const std::string& name, const std::string& path) +std::pair Identify::findImage(const cv::Mat& image, const cv::Mat& templ) { - Mat mat = imread(path); - if (mat.empty()) { - return false; + cv::Mat image_hsv; + cv::Mat templ_hsv; + cvtColor(image, image_hsv, COLOR_BGR2HSV); + cvtColor(templ, templ_hsv, COLOR_BGR2HSV); + + Mat matched; + matchTemplate(image_hsv, templ_hsv, matched, cv::TM_CCORR_NORMED); + + double minVal = 0, maxVal = 0; + cv::Point minLoc, maxLoc; + minMaxLoc(matched, &minVal, &maxVal, &minLoc, &maxLoc); + + return { maxVal, asst::Rect(maxLoc.x, maxLoc.y, templ.cols, templ.rows).center_zoom(0.8) }; +} + +std::pair Identify::findImage(const cv::Mat& cur, const std::string& templ) +{ + if (m_matMap.find(templ) == m_matMap.end()) { + return { 0, asst::Rect() }; } - m_matMap.emplace(name, mat); - return true; -} \ No newline at end of file + return findImage(cur, m_matMap.at(templ)); +} + +std::pair Identify::findImageWithFile(const cv::Mat& cur, const std::string& filename) +{ + Mat mat = imread(filename); + if (mat.empty()) { + return { 0, asst::Rect() }; + } + return findImage(cur, mat); +} diff --git a/MeoAssistance/src/WinMacro.cpp b/MeoAssistance/src/WinMacro.cpp index ca09fdb64d..a51acc7dbd 100644 --- a/MeoAssistance/src/WinMacro.cpp +++ b/MeoAssistance/src/WinMacro.cpp @@ -10,9 +10,9 @@ #include #include "Configer.h" -#include "AssDef.h" +#include "AsstDef.h" -using namespace MeoAssistance; +using namespace asst; WinMacro::WinMacro(HandleType type) : m_handle_type(type), @@ -25,13 +25,17 @@ bool WinMacro::findHandle() json::array handle_arr; switch (m_handle_type) { case HandleType::BlueStacksControl: - handle_arr = Configer::handleObj["BlueStacksControl"].as_array(); + m_xOffset = Configer::handleObj["BlueStacks"]["xOffset"].as_integer(); + m_yOffset = Configer::handleObj["BlueStacks"]["yOffset"].as_integer(); + handle_arr = Configer::handleObj["BlueStacks"]["Control"].as_array(); break; case HandleType::BlueStacksView: - handle_arr = Configer::handleObj["BlueStacksView"].as_array(); + handle_arr = Configer::handleObj["BlueStacks"]["View"].as_array(); break; case HandleType::BlueStacksWindow: - handle_arr = Configer::handleObj["BlueStacksWindow"].as_array(); + m_width = Configer::handleObj["BlueStacks"]["Width"].as_integer(); + m_height = Configer::handleObj["BlueStacks"]["Height"].as_integer(); + handle_arr = Configer::handleObj["BlueStacks"]["Window"].as_array(); break; default: std::cerr << "handle type error! " << static_cast(m_handle_type) << std::endl; @@ -63,6 +67,11 @@ bool WinMacro::resizeWindow(int width, int height) return ::MoveWindow(m_handle, 0, 0, width / getScreenScale(), height / getScreenScale(), true); } +bool WinMacro::resizeWindow() +{ + return resizeWindow(m_width, m_height); +} + double WinMacro::getScreenScale() { static double scale = 0; @@ -103,10 +112,10 @@ bool WinMacro::click(const Point& p) return false; } - int x = p.x / getScreenScale(); - int y = p.y / getScreenScale(); + int x = (p.x + m_xOffset) / getScreenScale(); + int y = (p.y + m_yOffset) / getScreenScale(); - DebugTrace("click: %d, %d", x, y); + DebugTrace("click, raw: %d, %d, cor: %d, %d", p.x, p.y, x, y); LPARAM lparam = MAKELPARAM(x, y); @@ -127,16 +136,17 @@ bool WinMacro::clickRange(const Rect& rect) x = rect.x; } else { - std::poisson_distribution x_rand(rect.width); - x = x_rand(m_rand_engine) + rect.x; + int x_rand = std::poisson_distribution(rect.width / 2)(m_rand_engine); + + x = x_rand + rect.x; } if (rect.height == 0) { y = rect.y; } else { - std::poisson_distribution y_rand(rect.height); - y = y_rand(m_rand_engine) + rect.y; + int y_rand = std::poisson_distribution(rect.height / 2 )(m_rand_engine); + y = y_rand + rect.y; } return click({ x, y }); @@ -147,9 +157,11 @@ Rect WinMacro::getWindowRect() RECT rect; bool ret = ::GetWindowRect(m_handle, &rect); if (!ret) { - return { 0, 0, 0 ,0 }; + return Rect(); } - return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top } *getScreenScale(); + return Rect{ rect.left, rect.top, + static_cast((rect.right - rect.left) * getScreenScale()), + static_cast((rect.bottom - rect.top) * getScreenScale()) } ; } cv::Mat WinMacro::getImage(const Rect& rect) diff --git a/README.md b/README.md index 97e1083ed8..7bdd21c5fb 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ A game assistance for Arknights ## 使用说明 -### alpha_2 版本 +### alpha_3 版本 1. 使用蓝叠模拟器打开明日方舟,进入有**蓝色的开始行动按钮**的界面,勾上代理指挥 -2. 解压压缩包,**使用管理员权限**,打开"Test.exe" +2. 解压压缩包,**使用管理员权限**,打开"Sanity.exe" 3. 目前只有最基本的功能,刷完体力+体力药就会自动停了…… ## Todo @@ -28,19 +28,20 @@ A game assistance for Arknights - [ ] 图形化界面 - [ ] 功能 - - [ ] 支持剿灭 + - [x] 支持剿灭 - [ ] 支持刷指定次数 - [ ] 支持使模拟器窗口不可见 - [x] 自动吃体力药 - [ ] 自动吃石头(根据设置,指定数量) - [ ] 代理失败的情况 - [ ] 支持更多模拟器 - - [ ] 支持等级提升 + - [x] 支持等级提升 - [ ] 支持凌晨4点更新数据 - [ ] 信用访问 - [ ] 基建收菜 -- [ ] 算法 - - [ ] 更换算法为找图,而不是当前的区域相似度对比 +- [x] 算法 + - [x] 更换算法为找图,而不是当前的区域相似度对比 + - [ ] 优化算法效率 ## 致谢 diff --git a/Tools/Sanity/main.cpp b/Tools/Sanity/main.cpp index 8ab6a2a0d3..d4f7af1280 100644 --- a/Tools/Sanity/main.cpp +++ b/Tools/Sanity/main.cpp @@ -2,22 +2,22 @@ int main(int argc, char** argv) { - using namespace MeoAssistance; + using namespace asst; - Assistance ass; - if (!ass.setSimulatorType(SimulatorType::BlueStacks)) { - DebugTraceError("Find Simulator Error"); + Assistance asst; + if (!asst.setSimulatorType(SimulatorType::BlueStacks)) { + DebugTraceError("Can't Find Simulator or Permission denied."); getchar(); return -1; } DebugTraceInfo("Start"); - ass.start(); + asst.start(); getchar(); DebugTraceInfo("Stop"); - ass.stop(); + asst.stop(); return 0; } \ No newline at end of file diff --git a/resource/MedicineConfirm.png b/resource/MedicineConfirm.png new file mode 100644 index 0000000000..45b7e577d8 Binary files /dev/null and b/resource/MedicineConfirm.png differ diff --git a/resource/MissionSucceed.png b/resource/MissionSucceed.png deleted file mode 100644 index 5049e6df6f..0000000000 Binary files a/resource/MissionSucceed.png and /dev/null differ diff --git a/resource/PRTS.png b/resource/PRTS.png index 50b8a5897b..fb360f4f7e 100644 Binary files a/resource/PRTS.png and b/resource/PRTS.png differ diff --git a/resource/StartButton1.png b/resource/StartButton1.png index 8248bc57a2..47d3bf633f 100644 Binary files a/resource/StartButton1.png and b/resource/StartButton1.png differ diff --git a/resource/StartButton2.png b/resource/StartButton2.png index 1e45c4d6c1..00db0efc4c 100644 Binary files a/resource/StartButton2.png and b/resource/StartButton2.png differ diff --git a/resource/UseMedicine.png b/resource/UseMedicine.png index 473057bb35..2f1e6a6962 100644 Binary files a/resource/UseMedicine.png and b/resource/UseMedicine.png differ diff --git a/resource/UseStone.png b/resource/UseStone.png index 70244b59f4..d01350133f 100644 Binary files a/resource/UseStone.png and b/resource/UseStone.png differ diff --git a/resource/config.json b/resource/config.json index d7874f77cb..29b20c6982 100644 --- a/resource/config.json +++ b/resource/config.json @@ -1,112 +1,78 @@ { "version": 0.1, + "options": { + "delay": 2000 + }, "handle": { - "BlueStacksControl": [ - { - "class": "BS2CHINAUI", - "window": "BlueStacks App Player" - }, - { - "class": "BS2CHINAUI", - "window": "HOSTWND" - }, - { - "class": "WindowsForms10.Window.8.app.0.34f5582_r6_ad1", - "window": "BlueStacks Android PluginAndroid" - } - ], - "BlueStacksView": [ - { - "class": "BS2CHINAUI", - "window": "BlueStacks App Player" - } - ], - "BlueStacksWindow": [ - { - "class": "BS2CHINAUI", - "window": "BlueStacks App Player" - } - ] + "BlueStacks": { + "Control": [ + { + "class": "BS2CHINAUI", + "window": "BlueStacks App Player" + }, + { + "class": "BS2CHINAUI", + "window": "HOSTWND" + }, + { + "class": "WindowsForms10.Window.8.app.0.34f5582_r6_ad1", + "window": "BlueStacks Android PluginAndroid" + } + ], + "View": [ + { + "class": "BS2CHINAUI", + "window": "BlueStacks App Player" + } + ], + "Window": [ + { + "class": "BS2CHINAUI", + "window": "BlueStacks App Player" + } + ], + "Width": 1294, + "Height": 773, + "xOffset": -7, + "yOffset": -47 + } }, "data": { + "Random": { + "filename": "", + "threshold": 0, + "type": "clickRand" + }, "UseMedicine": { - "viewRect": [ - 571, - 118, - 621, - 504 - ], "filename": "UseMedicine.png", - "similarity": 0.999, - "type": "click", - "ctrlRect": [ - 994, - 523, - 30, - 17 - ] + "threshold": 0.99, + "type": "next", + "next": { + "name": "MedicineConfirm", + "filename": "MedicineConfirm.png", + "threshold": 0.99, + "type": "clickSelf" + } + }, + "PRTS": { + "filename": "PRTS.png", + "threshold": 0.99, + "type": "doNothing" }, "UseStone": { - "viewRect": [ - 571, - 118, - 621, - 504 - ], "filename": "UseStone.png", - "similarity": 0.999, + "threshold": 0.999, "type": "stop" }, - "MissionSucceed": { - "viewRect": [ - 186, - 521, - 47, - 26 - ], - "filename": "MissionSucceed.png", - "similarity": 0.4, - "type": "click", - "ctrlRect": [ - 977, - 596, - 163, - 29 - ] - }, "StartButton1": { - "viewRect": [ - 968, - 627, - 193, - 70 - ], "filename": "StartButton1.png", - "similarity": 0.99, - "type": "click", - "ctrlRect": [ - 977, - 596, - 163, - 29 - ] + "threshold": 0.99, + "type": "clickSelf" }, "StartButton2": { - "viewRect": [ - 966, - 386, - 126, - 259 - ], "filename": "StartButton2.png", - "similarity": 0.99, - "type": "click", - "ctrlRect": [ - 975, - 353, - 97, - 230 - ] + "threshold": 0.99, + "type": "clickSelf" } } } \ No newline at end of file