try to supoort MuMu

This commit is contained in:
MistEO
2021-07-18 02:40:57 +08:00
parent 70544e7809
commit 1a0add784d
14 changed files with 217 additions and 38 deletions

View File

@@ -22,10 +22,10 @@ namespace asst {
std::optional<std::string> setSimulator(const std::string & simulator_name = std::string());
void start(const std::string & task);
void stop();
void stop(bool block = true);
bool setParam(const std::string& type, const std::string& param, const std::string& value);
std::optional<std::string> getParam(const std::string& type, const std::string& param);
private:
static void workingProc(Assistance* pThis);

View File

@@ -12,6 +12,7 @@ extern __declspec(dllexport) bool AsstCatchSimulator(asst::Assistance* p_asst);
extern __declspec(dllexport) void AsstStart(asst::Assistance* p_asst, const char* task);
extern __declspec(dllexport) void AsstStop(asst::Assistance* p_asst);
extern __declspec(dllexport) bool AsstSetParam(asst::Assistance* p_asst, const char* type, const char* param, const char* value);
extern __declspec(dllexport) bool AsstGetParam(asst::Assistance* p_asst, const char* type, const char* param, char * buffer, int buffer_size);
#ifdef __cplusplus
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include <mutex>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
@@ -110,4 +111,16 @@ namespace asst {
{
DebugPrint("ERR", std::forward<Args>(args)...);
}
static std::string replace_all_distinct(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;
}
}

View File

@@ -3,6 +3,8 @@
#include <string>
#include <unordered_map>
#include <vector>
#include <optional>
#include "AsstDef.h"
namespace asst {
@@ -10,14 +12,21 @@ namespace asst {
std::string className;
std::string windowName;
};
struct AdbCmd {
std::string path;
std::string connect;
std::string click;
};
struct SimulatorInfo {
std::vector<HandleInfo> window;
std::vector<HandleInfo> view;
std::vector<HandleInfo> control;
bool is_adb = false;
AdbCmd adb;
int width = 0;
int height = 0;
int xOffset = 0;
int yOffset = 0;
int x_offset = 0;
int y_offset = 0;
};
enum class TaskType {
@@ -58,6 +67,9 @@ namespace asst {
static std::unordered_map<std::string, SimulatorInfo> m_handles;
static bool setParam(const std::string& type, const std::string& param, const std::string& value);
static std::optional<std::string> getParam(const std::string& type, const std::string& param);
static void clearExecTimes();
private:
Configer() = default;

View File

@@ -30,10 +30,12 @@ namespace asst {
const std::string m_simulator_name;
const HandleType m_handle_type;
HWND m_handle = NULL;
bool m_is_adb = false;
std::string m_click_cmd;
std::minstd_rand m_rand_engine;
int m_width = 0;
int m_height = 0;
int m_xOffset = 0;
int m_yOffset = 0;
int m_x_offset = 0;
int m_y_offset = 0;
};
}

View File

@@ -65,7 +65,7 @@ std::optional<std::string> Assistance::setSimulator(const std::string& simulator
else {
ret = create_handles(simulator_name);
}
if (ret && m_pWindow->resizeWindow()) {
if (ret && m_pWindow->showWindow() && m_pWindow->resizeWindow() ) {
m_inited = true;
return cor_name;
}
@@ -89,13 +89,16 @@ void Assistance::start(const std::string& task)
m_condvar.notify_one();
}
void Assistance::stop()
void Assistance::stop(bool block)
{
std::unique_lock<std::mutex> lock(m_mutex);
std::unique_lock<std::mutex> lock;
if (block) {
lock = std::unique_lock<std::mutex>(m_mutex);
}
m_thread_running = false;
m_next_tasks.clear();
m_pIder->clear_cache();
Configer::clearExecTimes();
}
bool Assistance::setParam(const std::string& type, const std::string& param, const std::string& value)
@@ -103,6 +106,11 @@ bool Assistance::setParam(const std::string& type, const std::string& param, con
return Configer::setParam(type, param, value);
}
std::optional<std::string> Assistance::getParam(const std::string& type, const std::string& param)
{
return Configer::getParam(type, param);
}
void Assistance::workingProc(Assistance* pThis)
{
while (!pThis->m_thread_exit) {
@@ -141,8 +149,7 @@ void Assistance::workingProc(Assistance* pThis)
}
if (task.exec_times >= task.max_times) {
DebugTraceInfo("Reached limit, Stop.");
pThis->m_thread_running = false;
pThis->m_next_tasks.clear();
pThis->stop(false);
continue;
}
pThis->m_pCtrl->clickRange(matched_rect);
@@ -155,8 +162,7 @@ void Assistance::workingProc(Assistance* pThis)
break;
case TaskType::Stop:
DebugTrace("TaskType is Stop");
pThis->m_thread_running = false;
pThis->m_next_tasks.clear();
pThis->stop(false);
continue;
break;
default:

View File

@@ -1,5 +1,6 @@
#include "AsstCaller.h"
#include <string.h>
asst::Assistance* CreateAsst()
{
@@ -54,5 +55,18 @@ bool AsstSetParam(asst::Assistance* p_asst, const char* type, const char* param,
return false;
}
p_asst->setParam(type, param, value);
return p_asst->setParam(type, param, value);
}
bool AsstGetParam(asst::Assistance* p_asst, const char* type, const char* param, char * buffer, int buffer_size)
{
if (p_asst == NULL) {
return false;
}
auto ret = p_asst->getParam(type, param);
if (!ret) {
return false;
}
strcpy_s(buffer, buffer_size, ret.value().c_str());
return true;
}

View File

@@ -75,13 +75,13 @@ bool Configer::reload()
DebugTraceError("Task:", name, "error:", type);
return false;
}
if (task_json.as_object().exist("maxTimes")) {
if (task_json.exist("maxTimes")) {
task_info.max_times = task_json["maxTimes"].as_integer();
}
if (task_json.as_object().exist("preDelay")) {
if (task_json.exist("preDelay")) {
task_info.pre_delay = task_json["preDelay"].as_integer();
}
if (task_json.as_object().exist("rearDelay")) {
if (task_json.exist("rearDelay")) {
task_info.rear_delay = task_json["rearDelay"].as_integer();
}
@@ -119,10 +119,17 @@ bool Configer::reload()
handle_info.windowName = info["window"].as_string();
simulator_info.control.emplace_back(handle_info);
}
if (simulator_json.exist("adbControl")) {
simulator_info.is_adb = true;
// meojson的bug暂时没空修先转个字符串
simulator_info.adb.path = replace_all_distinct(simulator_json["adbControl"]["path"].as_string(), "\\\\", "\\");
simulator_info.adb.connect = simulator_json["adbControl"]["connect"].as_string();
simulator_info.adb.click = simulator_json["adbControl"]["click"].as_string();
}
simulator_info.width = simulator_json["width"].as_integer();
simulator_info.height = simulator_json["height"].as_integer();
simulator_info.xOffset = simulator_json["xOffset"].as_integer();
simulator_info.yOffset = simulator_json["yOffset"].as_integer();
simulator_info.x_offset = simulator_json["xOffset"].as_integer();
simulator_info.y_offset = simulator_json["yOffset"].as_integer();
m_handles.emplace(name, simulator_info);
}
@@ -171,4 +178,19 @@ bool Configer::setParam(const std::string& type, const std::string& param, const
m_tasks[param].max_times = std::stoi(value);
}
return true;
}
std::optional<std::string> Configer::getParam(const std::string& type, const std::string& param)
{
if (type == "task.execTimes" && m_tasks.find(param) != m_tasks.cend()) {
return std::to_string(m_tasks.at(param).exec_times);
}
return std::nullopt;
}
void Configer::clearExecTimes()
{
for (auto&& t : m_tasks) {
t.second.exec_times = 0;
}
}

View File

@@ -40,8 +40,9 @@ bool WinMacro::findHandle()
handle_vec = info.view;
break;
case HandleType::Control:
m_xOffset = info.xOffset;
m_yOffset = info.yOffset;
m_is_adb = info.is_adb;
m_x_offset = info.x_offset;
m_y_offset = info.y_offset;
handle_vec = info.control;
break;
default:
@@ -77,7 +78,29 @@ bool WinMacro::findHandle()
window_wbuff = NULL;
}
}
if (m_is_adb && m_handle != NULL) {
DWORD pid = 0;
::GetWindowThreadProcessId(m_handle, &pid);
HANDLE handle = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
LPSTR path_buff = new CHAR[MAX_PATH];
memset(path_buff, 0, MAX_PATH);
DWORD buff_size = MAX_PATH;
QueryFullProcessImageNameA(handle, 0, path_buff, &buff_size);
std::string adb_dir = path_buff;
if (path_buff != NULL) {
delete[] path_buff;
path_buff = NULL;
}
size_t pos = adb_dir.find_last_of('\\') + 1;
adb_dir = adb_dir.substr(0, pos);
adb_dir = '"' + replace_all_distinct(info.adb.path, "[EmulatorPath]", adb_dir) + '"';
std::string connect_cmd = adb_dir + info.adb.connect;
int ret = system(connect_cmd.c_str());
DebugTrace("Call", connect_cmd, "—— ret", ret);
m_click_cmd = adb_dir + info.adb.click;
}
DebugTrace("Handle:", m_handle, "Name:", m_simulator_name, "Type:", static_cast<int>(m_handle_type));
if (m_handle != NULL) {
@@ -111,7 +134,7 @@ bool WinMacro::showWindow()
return false;
}
return ::ShowWindow(m_handle, SW_SHOW);
return ::ShowWindow(m_handle, SW_RESTORE);
}
bool WinMacro::hideWindow()
@@ -163,17 +186,29 @@ bool WinMacro::click(const Point& p)
return false;
}
int x = (p.x + m_xOffset) / getScreenScale();
int y = (p.y + m_yOffset) / getScreenScale();
DebugTrace("click, raw:", p.x, p.y, "cor:", x, y);
LPARAM lparam = MAKELPARAM(x, y);
if (m_is_adb) {
int x = (p.x + m_x_offset);
int y = (p.y + m_y_offset);
std::string cur_cmd = replace_all_distinct(m_click_cmd, "[x]", std::to_string(x));
cur_cmd = replace_all_distinct(cur_cmd, "[y]", std::to_string(y));
int ret = system(cur_cmd.c_str());
DebugTrace("Call", cur_cmd, "—— ret", ret);
return !ret;
}
else {
int x = (p.x + m_x_offset) / getScreenScale();
int y = (p.y + m_y_offset) / getScreenScale();
DebugTrace("Click, raw:", p.x, p.y, "cor:", x, y);
::SendMessage(m_handle, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
::SendMessage(m_handle, WM_LBUTTONUP, 0, lparam);
LPARAM lparam = MAKELPARAM(x, y);
return true;
::SendMessage(m_handle, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
::SendMessage(m_handle, WM_LBUTTONUP, 0, lparam);
return true;
}
}
bool WinMacro::clickRange(const Rect& rect)
@@ -242,12 +277,12 @@ cv::Mat WinMacro::getImage(const Rect& rect)
DeleteDC(memDC);
ReleaseDC(m_handle, pDC);
/*
#ifdef _DEBUG
std::string filename = GetCurrentDir() + "\\print.bmp";
cv::imwrite(filename, dst_mat);
#endif
*/
/*
#ifdef _DEBUG
std::string filename = GetCurrentDir() + "\\print.bmp";
cv::imwrite(filename, dst_mat);
#endif
*/
return dst_mat;
}

View File

@@ -15,5 +15,6 @@
<Button x:Name="button_stop" Content="停止" HorizontalAlignment="Left" Margin="50,280,0,0" VerticalAlignment="Top" Width="300" Height="50" Click="button_Click_stop"/>
<Label x:Name="catch_status" Content="" HorizontalAlignment="Left" Margin="50,30,0,0" VerticalAlignment="Top"/>
<Button x:Name="button_visit" Content="访问基建" HorizontalAlignment="Left" Margin="230,200,0,0" VerticalAlignment="Top" Width="120" Height="50" Click="button_Click_visit"/>
<Label x:Name="exec_times" Content="" HorizontalAlignment="Left" Margin="230,30,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>

View File

@@ -13,6 +13,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Threading;
namespace MeoAsstGui
{
@@ -28,15 +29,19 @@ namespace MeoAsstGui
[DllImport("MeoAssistance.dll")] static public extern void AsstStart(IntPtr ptr, string task);
[DllImport("MeoAssistance.dll")] static public extern void AsstStop(IntPtr ptr);
[DllImport("MeoAssistance.dll")] static public extern bool AsstSetParam(IntPtr p_asst, string type, string param, string value);
[DllImport("MeoAssistance.dll")] static public extern bool AsstGetParam(IntPtr p_asst, string type, string param, [In, Out] StringBuilder lp_string, int buffer_size);
private IntPtr p_asst;
private DispatcherTimer update_times = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
p_asst = CreateAsst();
update_times.Tick += new EventHandler(updateExecTimes);
update_times.Interval = TimeSpan.FromSeconds(1);
}
~MainWindow()
{
@@ -48,12 +53,15 @@ namespace MeoAsstGui
bool catched = AsstCatchSimulator(p_asst);
catch_status.Content = "捕获模拟器窗口:" + catched;
AsstStart(p_asst, "SanityBegin");
update_times.Start();
}
private void button_Click_stop(object sender, RoutedEventArgs e)
{
AsstStop(p_asst);
catch_status.Content = "";
update_times.Stop();
exec_times.Content = "";
}
private void checkBox_useMedicine_Checked(object sender, RoutedEventArgs e)
@@ -91,5 +99,12 @@ namespace MeoAsstGui
catch_status.Content = "捕获模拟器窗口:" + catched;
AsstStart(p_asst, "VisitBegin");
}
private void updateExecTimes(object sender, EventArgs e)
{
StringBuilder buff = new StringBuilder(16);
AsstGetParam(p_asst, "task.execTimes", "StartButton2", buff, 16);
exec_times.Content = "已运行 " + buff + " 次";
}
}
}

Submodule meojson updated: e66deff929...d6d07f5e6c

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 KiB

After

Width:  |  Height:  |  Size: 396 KiB

View File

@@ -147,6 +147,64 @@
"height": 769,
"xOffset": 0,
"yOffset": -42
},
"MuMuAsst": {
"window": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - 星云引擎"
}
],
"view": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - 星云引擎"
}
],
"control": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - 星云引擎"
}
],
"adbControl": {
"path": "[EmulatorPath]..\\vmonitor\\bin\\adb_server.exe",
"connect": " connect 127.0.0.1:7555",
"click": " shell input tap [x] [y]"
},
"width": 1280,
"height": 809,
"xOffset": 0,
"yOffset": -36
},
"MuMuEmulator": {
"window": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - MuMu模拟器"
}
],
"view": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - MuMu模拟器"
}
],
"control": [
{
"class": "Qt5QWindowIcon",
"window": "明日方舟 - MuMu模拟器"
}
],
"adbControl": {
"path": "[EmulatorPath]..\\vmonitor\\bin\\adb_server.exe",
"connect": " connect 127.0.0.1:7555",
"click": " shell input tap [x] [y]"
},
"width": 1280,
"height": 809,
"xOffset": 0,
"yOffset": -36
}
},
"tasks": {
@@ -188,7 +246,7 @@
"filename": "StartButton2.png",
"threshold": 0.99,
"type": "clickSelf",
"rearDelay": 10000,
"rearDelay": 10000,
"next": [
"PRTS"
]