mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-02 18:50:30 +08:00
Compare commits
9 Commits
dev-v2
...
release.al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
102ee1cb5c | ||
|
|
ba9176af93 | ||
|
|
f46e2945dc | ||
|
|
22cb7ba745 | ||
|
|
e8d91d3e96 | ||
|
|
b2b4daeeed | ||
|
|
4090400fa4 | ||
|
|
0937be8c02 | ||
|
|
6b216b0cac |
@@ -10,6 +10,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeoAssistance", "MeoAssista
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmeojson", "meojson\test\vsproj\meojson\libmeojson\libmeojson.vcxproj", "{9CC7838E-D5FB-4771-848D-5F83D638C5AD}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Tools\Test\Test.vcxproj", "{36BC08F3-71CF-429A-AE69-291BE8962CB2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300} = {362D1E30-F5AE-4279-9985-65C27B3BA300}
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD} = {9CC7838E-D5FB-4771-848D-5F83D638C5AD}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -34,6 +40,14 @@ Global
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Release|x64.Build.0 = Release|x64
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Release|x86.Build.0 = Release|Win32
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Debug|x64.Build.0 = Debug|x64
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Debug|x86.Build.0 = Debug|Win32
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Release|x64.ActiveCfg = Release|x64
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Release|x64.Build.0 = Release|x64
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Release|x86.ActiveCfg = Release|Win32
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
#include "Assistance.h"
|
||||
|
||||
#include "WinMacro.h"
|
||||
|
||||
using namespace MeoAssistance;
|
||||
|
||||
Assistance::Assistance()
|
||||
: m_control_thread(control_function, this),
|
||||
m_identify_thread(identify_function, this)
|
||||
{
|
||||
}
|
||||
|
||||
Assistance::~Assistance()
|
||||
{
|
||||
m_control_exit = true;
|
||||
m_control_running = false;
|
||||
m_control_cv.notify_all();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
bool Assistance::setSimulatorType(SimulatorType type)
|
||||
{
|
||||
stop();
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
std::queue<Task> empty;
|
||||
m_tasks.swap(empty);
|
||||
int int_type = static_cast<int>(type);
|
||||
m_pCtrl = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::Control)));
|
||||
m_pWindow = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::Window)));
|
||||
m_pView = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::View)));
|
||||
return m_pCtrl->findHandle() && m_pWindow->findHandle() && m_pView->findHandle();
|
||||
}
|
||||
|
||||
void Assistance::start()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
|
||||
m_control_running = true;
|
||||
m_identify_running = true;
|
||||
m_control_cv.notify_all();
|
||||
m_identify_cv.notify_all();
|
||||
}
|
||||
|
||||
void Assistance::stop()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
|
||||
m_control_running = false;
|
||||
m_identify_running = false;
|
||||
}
|
||||
|
||||
void Assistance::identify_function(Assistance* pThis)
|
||||
{
|
||||
while (!pThis->m_identify_exit) {
|
||||
std::unique_lock<std::mutex> lock(pThis->m_tasks_mutex);
|
||||
if (pThis->m_identify_running) {
|
||||
pThis->m_pView->getImage(pThis->m_pView->getWindowRect());
|
||||
pThis->m_tasks.emplace(Task::StartButton1);
|
||||
pThis->m_control_cv.notify_all();
|
||||
pThis->m_identify_cv.wait_for(lock, std::chrono::milliseconds(3000));
|
||||
}
|
||||
else {
|
||||
pThis->m_identify_cv.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Assistance::control_function(Assistance* pThis)
|
||||
{
|
||||
pThis->m_pWindow->resizeWindow(1200, 720);
|
||||
|
||||
while (!pThis->m_control_exit) {
|
||||
std::unique_lock<std::mutex> lock(pThis->m_tasks_mutex);
|
||||
if (pThis->m_control_running && !pThis->m_tasks.empty()) {
|
||||
const Task task = pThis->m_tasks.front();
|
||||
pThis->m_tasks.pop();
|
||||
lock.unlock();
|
||||
|
||||
pThis->run_task(task);
|
||||
}
|
||||
else {
|
||||
pThis->m_control_cv.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Assistance::run_task(Task task)
|
||||
{
|
||||
switch (task)
|
||||
{
|
||||
case MeoAssistance::Assistance::Task::StartButton1:
|
||||
return m_pCtrl->click({ 1060, 600 });
|
||||
break;
|
||||
case MeoAssistance::Assistance::Task::StartButton2:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
namespace MeoAssistance {
|
||||
|
||||
class WinMacro;
|
||||
|
||||
class Identify
|
||||
{
|
||||
public:
|
||||
Identify() = default;
|
||||
~Identify() = default;
|
||||
double imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs);
|
||||
private:
|
||||
};
|
||||
}
|
||||
@@ -18,6 +18,19 @@
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\AssDef.h" />
|
||||
<ClInclude Include="include\Assistance.h" />
|
||||
<ClInclude Include="include\Configer.h" />
|
||||
<ClInclude Include="include\Identify.h" />
|
||||
<ClInclude Include="include\WinMacro.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Assistance.cpp" />
|
||||
<ClCompile Include="src\Configer.cpp" />
|
||||
<ClCompile Include="src\Identify.cpp" />
|
||||
<ClCompile Include="src\WinMacro.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
@@ -40,13 +53,13 @@
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
@@ -78,13 +91,13 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(OPENCV_PATH)\include\opencv2;$(OPENCV_PATH)\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)meojson\test\vsproj\meojson\x64\Debug;$(OPENCV_PATH)\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(ProjectDir)include;$(SolutionDir)meojson\include;$(OPENCV_PATH)\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(TargetDir);$(OPENCV_PATH)\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(OPENCV_PATH)\include\opencv2;$(OPENCV_PATH)\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)meojson\test\vsproj\meojson\x64\Release;$(OPENCV_PATH)\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||
<IncludePath>$(ProjectDir)include;$(SolutionDir)meojson\include;$(OPENCV_PATH)\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(TargetDir);$(OPENCV_PATH)\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -122,12 +135,25 @@
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world452d.lib;libmeojson.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>$(TargetDir)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /e /y /i $(SolutionDir)resource $(TargetDir)resource</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>copy resource</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@@ -138,6 +164,8 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -145,21 +173,26 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world452.lib;libmeojson.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>$(TargetDir)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /e /y /i $(SolutionDir)resource $(TargetDir)resource</Command>
|
||||
</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Message>copy resource</Message>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AssDef.h" />
|
||||
<ClInclude Include="Assistance.h" />
|
||||
<ClInclude Include="Identify.h" />
|
||||
<ClInclude Include="WinMacro.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Assistance.cpp" />
|
||||
<ClCompile Include="Identify.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="WinMacro.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties _1_1_4resource_4config_1json__JsonSchema="https://beaujs.com/schema.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -1,207 +0,0 @@
|
||||
#include "WinMacro.h"
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WinUser.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace MeoAssistance;
|
||||
|
||||
WinMacro::WinMacro(HandleType type)
|
||||
: m_handle_type(type),
|
||||
m_rand_engine(time(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
bool WinMacro::findHandle()
|
||||
{
|
||||
switch (m_handle_type) {
|
||||
case HandleType::BlueStacksControl: {
|
||||
HWND temp_handle = ::FindWindow(L"BS2CHINAUI", L"BlueStacks App Player");
|
||||
temp_handle = ::FindWindowEx(temp_handle, NULL, L"BS2CHINAUI", L"HOSTWND");
|
||||
m_handle = ::FindWindowEx(temp_handle, NULL, L"WindowsForms10.Window.8.app.0.34f5582_r6_ad1", L"BlueStacks Android PluginAndroid");
|
||||
} break;
|
||||
case HandleType::BlueStacksView:
|
||||
case HandleType::BlueStacksWindow:
|
||||
m_handle = ::FindWindow(L"BS2CHINAUI", L"BlueStacks App Player");
|
||||
break;
|
||||
default:
|
||||
std::cerr << "handle type error! " << static_cast<int>(m_handle_type) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::cout << "type: " << static_cast<int>(m_handle_type) << ", handle: " << m_handle << std::endl;
|
||||
#endif
|
||||
|
||||
if (m_handle != NULL) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WinMacro::resizeWindow(int width, int height)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Window))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::MoveWindow(m_handle, 0, 0, width, height, true);
|
||||
}
|
||||
|
||||
double WinMacro::getScreenScale()
|
||||
{
|
||||
// 获取窗口当前显示的监视器
|
||||
// 使用桌面的句柄.
|
||||
HWND hWnd = GetDesktopWindow();
|
||||
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// 获取监视器逻辑宽度与高度
|
||||
MONITORINFOEX miex;
|
||||
miex.cbSize = sizeof(miex);
|
||||
GetMonitorInfo(hMonitor, &miex);
|
||||
int cxLogical = (miex.rcMonitor.right - miex.rcMonitor.left);
|
||||
int cyLogical = (miex.rcMonitor.bottom - miex.rcMonitor.top);
|
||||
|
||||
// 获取监视器物理宽度与高度
|
||||
DEVMODE dm;
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm);
|
||||
int cxPhysical = dm.dmPelsWidth;
|
||||
int cyPhysical = dm.dmPelsHeight;
|
||||
|
||||
// 考虑状态栏大小,逻辑尺寸会比实际小
|
||||
double horzScale = ((double)cxPhysical / (double)cxLogical);
|
||||
double vertScale = ((double)cyPhysical / (double)cyLogical);
|
||||
|
||||
// 考虑状态栏大小,选择里面大的那个
|
||||
return std::max(horzScale, vertScale);
|
||||
}
|
||||
|
||||
bool WinMacro::click(Point p)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Control))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::cout << "click: " << p.x << ", " << p.y << std::endl;
|
||||
#endif
|
||||
|
||||
LPARAM lparam = MAKELPARAM(p.x, p.y);
|
||||
|
||||
::SendMessage(m_handle, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
|
||||
::SendMessage(m_handle, WM_LBUTTONUP, 0, lparam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinMacro::clickRange(Rect rect)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Control))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int x = 0, y = 0;
|
||||
if (rect.width == 0) {
|
||||
x = rect.x;
|
||||
}
|
||||
else {
|
||||
std::poisson_distribution<int> x_rand(rect.width);
|
||||
x = x_rand(m_rand_engine) + rect.x;
|
||||
|
||||
}
|
||||
if (rect.height == 0) {
|
||||
y = rect.y;
|
||||
}
|
||||
else {
|
||||
std::poisson_distribution<int> y_rand(rect.height);
|
||||
int y = y_rand(m_rand_engine) + rect.y;
|
||||
}
|
||||
|
||||
return click({ x, y });
|
||||
}
|
||||
|
||||
Rect WinMacro::getWindowRect()
|
||||
{
|
||||
RECT rect;
|
||||
bool ret = ::GetWindowRect(m_handle, &rect);
|
||||
if (!ret) {
|
||||
return { 0, 0, 0 ,0 };
|
||||
}
|
||||
double scale = getScreenScale();
|
||||
return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top } * scale;
|
||||
}
|
||||
|
||||
cv::Mat WinMacro::getImage(Rect rect)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::View))) {
|
||||
return cv::Mat();
|
||||
}
|
||||
|
||||
HDC pDC;// 源DC
|
||||
//判断是不是窗口句柄如果是的话不能使用GetDC来获取DC 不然截图会是黑屏
|
||||
if (m_handle == ::GetDesktopWindow())
|
||||
{
|
||||
pDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pDC = ::GetDC(m_handle);//获取屏幕DC(0为全屏,句柄则为窗口)
|
||||
}
|
||||
int BitPerPixel = ::GetDeviceCaps(pDC, BITSPIXEL);//获得颜色模式
|
||||
if (rect.width == 0 && rect.height == 0)//默认宽度和高度为全屏
|
||||
{
|
||||
rect.width = ::GetDeviceCaps(pDC, HORZRES); //设置图像宽度全屏
|
||||
rect.height = ::GetDeviceCaps(pDC, VERTRES); //设置图像高度全屏
|
||||
}
|
||||
HDC memDC;//内存DC
|
||||
memDC = ::CreateCompatibleDC(pDC);
|
||||
HBITMAP memBitmap, oldmemBitmap;//建立和屏幕兼容的bitmap
|
||||
memBitmap = ::CreateCompatibleBitmap(pDC, rect.width, rect.height);
|
||||
oldmemBitmap = (HBITMAP)::SelectObject(memDC, memBitmap);//将memBitmap选入内存DC
|
||||
if (m_handle == ::GetDesktopWindow())
|
||||
{
|
||||
BitBlt(memDC, 0, 0, rect.width, rect.height, pDC, rect.x, rect.y, SRCCOPY);//图像宽度高度和截取位置
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bret = ::PrintWindow(m_handle, memDC, PW_CLIENTONLY);
|
||||
if (!bret)
|
||||
{
|
||||
BitBlt(memDC, 0, 0, rect.width, rect.height, pDC, rect.x, rect.y, SRCCOPY);//图像宽度高度和截取位置
|
||||
}
|
||||
}
|
||||
|
||||
BITMAP bmp;
|
||||
GetObject(memBitmap, sizeof(BITMAP), &bmp);
|
||||
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel / 8;
|
||||
cv::Mat dst_mat;
|
||||
dst_mat.create(cv::Size(bmp.bmWidth, bmp.bmHeight), CV_MAKETYPE(CV_8U, nChannels));
|
||||
GetBitmapBits(memBitmap, bmp.bmHeight * bmp.bmWidth * nChannels, dst_mat.data);
|
||||
|
||||
DeleteObject(memBitmap);
|
||||
DeleteDC(memDC);
|
||||
ReleaseDC(m_handle, pDC);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// 获取程序当前路径
|
||||
char curpath[_MAX_PATH] = { 0 };
|
||||
::GetModuleFileNameA(NULL, curpath, _MAX_PATH);
|
||||
std::string filename(curpath);
|
||||
filename = filename.substr(0, filename.find_last_of('\\')) + "\\test.bmp";
|
||||
|
||||
cv::imwrite(filename, dst_mat);
|
||||
#endif
|
||||
|
||||
return dst_mat;
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "json_value.h"
|
||||
#include "json_array.h"
|
||||
|
||||
namespace MeoAssistance {
|
||||
enum class SimulatorType
|
||||
{
|
||||
@@ -33,4 +36,12 @@ namespace MeoAssistance {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
|
||||
static Rect jsonToRect(const json::array& arr)
|
||||
{
|
||||
if (arr.size() != 4) {
|
||||
return { 0, 0, 0, 0 };
|
||||
}
|
||||
return Rect(arr[0].as_integer(), arr[1].as_integer(), arr[2].as_integer(), arr[3].as_integer());
|
||||
}
|
||||
}
|
||||
@@ -10,13 +10,10 @@
|
||||
|
||||
namespace MeoAssistance {
|
||||
class WinMacro;
|
||||
class Identify;
|
||||
|
||||
class Assistance
|
||||
class __declspec(dllexport) Assistance
|
||||
{
|
||||
enum class Task {
|
||||
StartButton1,
|
||||
StartButton2
|
||||
};
|
||||
public:
|
||||
Assistance();
|
||||
~Assistance();
|
||||
@@ -30,13 +27,12 @@ namespace MeoAssistance {
|
||||
static void identify_function(Assistance* pThis); // 识别线程,生产者
|
||||
static void control_function(Assistance* pThis); // 控制线程,消费者
|
||||
|
||||
bool run_task(Task task);
|
||||
|
||||
std::shared_ptr<WinMacro> m_pCtrl = nullptr;
|
||||
std::shared_ptr<WinMacro> m_pWindow = nullptr;
|
||||
std::shared_ptr<WinMacro> m_pView = nullptr;
|
||||
std::shared_ptr<Identify> m_Ider = nullptr;
|
||||
|
||||
std::queue<Task> m_tasks;
|
||||
std::queue<Rect> m_tasks;
|
||||
std::mutex m_tasks_mutex;
|
||||
|
||||
std::thread m_control_thread;
|
||||
23
MeoAssistance/include/Configer.h
Normal file
23
MeoAssistance/include/Configer.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "json_object.h"
|
||||
|
||||
namespace MeoAssistance {
|
||||
class Configer
|
||||
{
|
||||
public:
|
||||
~Configer() = default;
|
||||
|
||||
static bool reload();
|
||||
static std::string getCurDir();
|
||||
static std::string getResDir();
|
||||
static json::object dataObj;
|
||||
static json::object handleObj;
|
||||
|
||||
private:
|
||||
Configer() = default;
|
||||
|
||||
static std::string m_curDir;
|
||||
};
|
||||
}
|
||||
23
MeoAssistance/include/Identify.h
Normal file
23
MeoAssistance/include/Identify.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "AssDef.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace MeoAssistance {
|
||||
|
||||
class WinMacro;
|
||||
|
||||
class Identify
|
||||
{
|
||||
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);
|
||||
private:
|
||||
std::unordered_map<std::string, cv::Mat> m_matMap;
|
||||
};
|
||||
}
|
||||
@@ -16,15 +16,15 @@ namespace MeoAssistance {
|
||||
|
||||
bool findHandle();
|
||||
bool resizeWindow(int Width, int Height);
|
||||
bool click(Point p);
|
||||
bool clickRange(Rect rect);
|
||||
cv::Mat getImage(Rect rect);
|
||||
bool click(const Point & p);
|
||||
bool clickRange(const Rect & rect);
|
||||
cv::Mat getImage(const Rect& rect);
|
||||
Rect getWindowRect();
|
||||
double getScreenScale();
|
||||
static double getScreenScale();
|
||||
private:
|
||||
|
||||
HandleType m_handle_type;
|
||||
HWND m_handle;
|
||||
HWND m_handle = NULL;
|
||||
std::minstd_rand m_rand_engine;
|
||||
};
|
||||
}
|
||||
147
MeoAssistance/src/Assistance.cpp
Normal file
147
MeoAssistance/src/Assistance.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "Assistance.h"
|
||||
|
||||
#include "WinMacro.h"
|
||||
#include "Configer.h"
|
||||
#include "Identify.h"
|
||||
|
||||
using namespace MeoAssistance;
|
||||
|
||||
Assistance::Assistance()
|
||||
{
|
||||
Configer::reload();
|
||||
|
||||
m_Ider = std::make_shared<Identify>();
|
||||
for (auto&& pair : Configer::dataObj)
|
||||
{
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
Assistance::~Assistance()
|
||||
{
|
||||
m_control_exit = true;
|
||||
m_control_running = false;
|
||||
m_control_cv.notify_all();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
bool Assistance::setSimulatorType(SimulatorType type)
|
||||
{
|
||||
stop();
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
std::queue<Rect> empty;
|
||||
m_tasks.swap(empty);
|
||||
int int_type = static_cast<int>(type);
|
||||
m_pCtrl = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::Control)));
|
||||
m_pWindow = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::Window)));
|
||||
m_pView = std::make_shared<WinMacro>(static_cast<HandleType>(int_type | static_cast<int>(HandleType::View)));
|
||||
bool ret = m_pCtrl->findHandle() && m_pWindow->findHandle() && m_pView->findHandle();
|
||||
if (ret) {
|
||||
m_pWindow->resizeWindow(1200, 720);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Assistance::start()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
|
||||
m_control_running = true;
|
||||
m_identify_running = true;
|
||||
m_control_cv.notify_all();
|
||||
m_identify_cv.notify_all();
|
||||
}
|
||||
|
||||
void Assistance::stop()
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_tasks_mutex);
|
||||
|
||||
m_control_running = false;
|
||||
m_identify_running = false;
|
||||
}
|
||||
|
||||
void Assistance::identify_function(Assistance* pThis)
|
||||
{
|
||||
while (!pThis->m_identify_exit) {
|
||||
std::unique_lock<std::mutex> lock(pThis->m_tasks_mutex);
|
||||
if (pThis->m_identify_running) {
|
||||
auto curImg = pThis->m_pView->getImage(pThis->m_pView->getWindowRect());
|
||||
|
||||
std::pair<std::string, json::value> matched;
|
||||
double max_similarity = 0;
|
||||
for (auto&& pair : Configer::dataObj) {
|
||||
double similarity = pThis->m_Ider->imgHistComp(curImg, pair.first, jsonToRect(pair.second["viewRect"].as_array()));
|
||||
#ifdef _DEBUG
|
||||
std::cout << pair.first << " Similarity: " << similarity << std::endl;
|
||||
#endif
|
||||
if (similarity >= pair.second["similarity"].as_double()) {
|
||||
if (similarity > max_similarity) {
|
||||
max_similarity = similarity;
|
||||
matched = pair;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_similarity != 0) {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "Max: " << matched.first << " , Similarity: " << max_similarity << std::endl;
|
||||
#endif
|
||||
std::string opType = matched.second["type"].as_string();
|
||||
if (opType == "click") {
|
||||
pThis->m_tasks.emplace(jsonToRect(matched.second["ctrlRect"].as_array()));
|
||||
}
|
||||
else if (opType == "stop") {
|
||||
#ifdef _DEBUG
|
||||
std::cout << "opType == stop " << std::endl;
|
||||
#endif
|
||||
pThis->m_control_running = false;
|
||||
pThis->m_identify_running = false;
|
||||
continue;
|
||||
}
|
||||
else if (opType == "donothing") {
|
||||
pThis->m_identify_cv.wait_for(lock, std::chrono::milliseconds(1000));
|
||||
continue;
|
||||
}
|
||||
pThis->m_control_cv.notify_all();
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << std::endl;
|
||||
#endif
|
||||
pThis->m_identify_cv.wait_for(lock, std::chrono::milliseconds(1000));
|
||||
}
|
||||
else {
|
||||
pThis->m_identify_cv.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Assistance::control_function(Assistance* pThis)
|
||||
{
|
||||
while (!pThis->m_control_exit) {
|
||||
std::unique_lock<std::mutex> lock(pThis->m_tasks_mutex);
|
||||
if (pThis->m_control_running && !pThis->m_tasks.empty()) {
|
||||
const Rect rect = pThis->m_tasks.front();
|
||||
pThis->m_tasks.pop();
|
||||
lock.unlock();
|
||||
|
||||
pThis->m_pCtrl->clickRange(rect);
|
||||
}
|
||||
else {
|
||||
pThis->m_control_cv.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
MeoAssistance/src/Configer.cpp
Normal file
54
MeoAssistance/src/Configer.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "Configer.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "json.h"
|
||||
|
||||
using namespace MeoAssistance;
|
||||
|
||||
json::object Configer::dataObj;
|
||||
json::object Configer::handleObj;
|
||||
|
||||
std::string Configer::m_curDir;
|
||||
|
||||
bool Configer::reload()
|
||||
{
|
||||
std::string filename = getResDir() + "config.json";
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto root = std::move(ret).value();
|
||||
dataObj = root["data"].as_object();
|
||||
handleObj = root["handle"].as_object();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Configer::getCurDir()
|
||||
{
|
||||
if (m_curDir.empty()) {
|
||||
char exepath_buff[_MAX_PATH] = { 0 };
|
||||
::GetModuleFileNameA(NULL, exepath_buff, _MAX_PATH);
|
||||
std::string exepath(exepath_buff);
|
||||
m_curDir = exepath.substr(0, exepath.find_last_of('\\') + 1);
|
||||
}
|
||||
return m_curDir;
|
||||
}
|
||||
|
||||
std::string Configer::getResDir()
|
||||
{
|
||||
return getCurDir() + "resource\\";
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Identify.h"
|
||||
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/imgproc/types_c.h>
|
||||
|
||||
@@ -29,4 +30,20 @@ double Identify::imgHistComp(const cv::Mat& lhs, const cv::Mat& rhs)
|
||||
normalize(rhs_hist, rhs_hist, 0, 1, NORM_MINMAX);
|
||||
|
||||
return compareHist(lhs_hist, rhs_hist, CV_COMP_CORREL);
|
||||
}
|
||||
|
||||
double Identify::imgHistComp(const cv::Mat& cur, const std::string& src, MeoAssistance::Rect compRect)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Mat mat = imread(path);
|
||||
if (mat.empty()) {
|
||||
return false;
|
||||
}
|
||||
m_matMap.emplace(name, mat);
|
||||
return true;
|
||||
}
|
||||
192
MeoAssistance/src/WinMacro.cpp
Normal file
192
MeoAssistance/src/WinMacro.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
#include "WinMacro.h"
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WinUser.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Configer.h"
|
||||
|
||||
using namespace MeoAssistance;
|
||||
|
||||
WinMacro::WinMacro(HandleType type)
|
||||
: m_handle_type(type),
|
||||
m_rand_engine(time(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
bool WinMacro::findHandle()
|
||||
{
|
||||
json::array handle_arr;
|
||||
switch (m_handle_type) {
|
||||
case HandleType::BlueStacksControl:
|
||||
handle_arr = Configer::handleObj["BlueStacksControl"].as_array();
|
||||
break;
|
||||
case HandleType::BlueStacksView:
|
||||
handle_arr = Configer::handleObj["BlueStacksView"].as_array();
|
||||
break;
|
||||
case HandleType::BlueStacksWindow:
|
||||
handle_arr = Configer::handleObj["BlueStacksWindow"].as_array();
|
||||
break;
|
||||
default:
|
||||
std::cerr << "handle type error! " << static_cast<int>(m_handle_type) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_handle = NULL;
|
||||
for (auto&& obj : handle_arr)
|
||||
{
|
||||
m_handle = ::FindWindowExA(m_handle, NULL, obj["class"].as_string().c_str(), obj["window"].as_string().c_str());
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::cout << "type: " << static_cast<int>(m_handle_type) << ", handle: " << m_handle << std::endl;
|
||||
#endif
|
||||
|
||||
if (m_handle != NULL) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WinMacro::resizeWindow(int width, int height)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Window))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::MoveWindow(m_handle, 0, 0, width / getScreenScale(), height / getScreenScale(), true);
|
||||
}
|
||||
|
||||
double WinMacro::getScreenScale()
|
||||
{
|
||||
static double scale = 0;
|
||||
if (scale == 0) {
|
||||
// 获取窗口当前显示的监视器
|
||||
// 使用桌面的句柄.
|
||||
HWND hWnd = GetDesktopWindow();
|
||||
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// 获取监视器逻辑宽度与高度
|
||||
MONITORINFOEX miex;
|
||||
miex.cbSize = sizeof(miex);
|
||||
GetMonitorInfo(hMonitor, &miex);
|
||||
int cxLogical = (miex.rcMonitor.right - miex.rcMonitor.left);
|
||||
int cyLogical = (miex.rcMonitor.bottom - miex.rcMonitor.top);
|
||||
|
||||
// 获取监视器物理宽度与高度
|
||||
DEVMODE dm;
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmDriverExtra = 0;
|
||||
EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm);
|
||||
int cxPhysical = dm.dmPelsWidth;
|
||||
int cyPhysical = dm.dmPelsHeight;
|
||||
|
||||
// 考虑状态栏大小,逻辑尺寸会比实际小
|
||||
double horzScale = ((double)cxPhysical / (double)cxLogical);
|
||||
double vertScale = ((double)cyPhysical / (double)cyLogical);
|
||||
|
||||
// 考虑状态栏大小,选择里面大的那个
|
||||
scale = std::max(horzScale, vertScale);
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
bool WinMacro::click(const Point& p)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Control))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int x = p.x / getScreenScale();
|
||||
int y = p.y / getScreenScale();
|
||||
#ifdef _DEBUG
|
||||
std::cout << "click: " << x << ", " << y << std::endl;
|
||||
#endif
|
||||
|
||||
LPARAM lparam = MAKELPARAM(x, y);
|
||||
|
||||
::SendMessage(m_handle, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
|
||||
::SendMessage(m_handle, WM_LBUTTONUP, 0, lparam);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinMacro::clickRange(const Rect& rect)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::Control))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int x = 0, y = 0;
|
||||
if (rect.width == 0) {
|
||||
x = rect.x;
|
||||
}
|
||||
else {
|
||||
std::poisson_distribution<int> x_rand(rect.width);
|
||||
x = x_rand(m_rand_engine) + rect.x;
|
||||
}
|
||||
|
||||
if (rect.height == 0) {
|
||||
y = rect.y;
|
||||
}
|
||||
else {
|
||||
std::poisson_distribution<int> y_rand(rect.height);
|
||||
y = y_rand(m_rand_engine) + rect.y;
|
||||
}
|
||||
|
||||
return click({ x, y });
|
||||
}
|
||||
|
||||
Rect WinMacro::getWindowRect()
|
||||
{
|
||||
RECT rect;
|
||||
bool ret = ::GetWindowRect(m_handle, &rect);
|
||||
if (!ret) {
|
||||
return { 0, 0, 0 ,0 };
|
||||
}
|
||||
return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top } *getScreenScale();
|
||||
}
|
||||
|
||||
cv::Mat WinMacro::getImage(const Rect& rect)
|
||||
{
|
||||
if (!(static_cast<int>(m_handle_type) & static_cast<int>(HandleType::View))) {
|
||||
return cv::Mat();
|
||||
}
|
||||
|
||||
HDC pDC;// 源DC
|
||||
pDC = ::GetDC(m_handle);//获取屏幕DC(0为全屏,句柄则为窗口)
|
||||
int BitPerPixel = ::GetDeviceCaps(pDC, BITSPIXEL);//获得颜色模式
|
||||
HDC memDC;//内存DC
|
||||
memDC = ::CreateCompatibleDC(pDC);
|
||||
HBITMAP memBitmap, oldmemBitmap;//建立和屏幕兼容的bitmap
|
||||
memBitmap = ::CreateCompatibleBitmap(pDC, rect.width, rect.height);
|
||||
oldmemBitmap = (HBITMAP)::SelectObject(memDC, memBitmap);//将memBitmap选入内存DC
|
||||
::PrintWindow(m_handle, memDC, PW_CLIENTONLY);
|
||||
|
||||
BITMAP bmp;
|
||||
GetObject(memBitmap, sizeof(BITMAP), &bmp);
|
||||
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel / 8;
|
||||
cv::Mat dst_mat;
|
||||
dst_mat.create(cv::Size(bmp.bmWidth, bmp.bmHeight), CV_MAKETYPE(CV_8U, nChannels));
|
||||
GetBitmapBits(memBitmap, bmp.bmHeight * bmp.bmWidth * nChannels, dst_mat.data);
|
||||
|
||||
DeleteObject(memBitmap);
|
||||
DeleteDC(memDC);
|
||||
ReleaseDC(m_handle, pDC);
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::string filename = Configer::getCurDir() + "\\test.bmp";
|
||||
cv::imwrite(filename, dst_mat);
|
||||
#endif
|
||||
|
||||
return dst_mat;
|
||||
}
|
||||
47
README.md
47
README.md
@@ -4,4 +4,49 @@ A game assistance for Arknights
|
||||
|
||||
一款明日方舟的游戏辅助,目前仅支持蓝叠模拟器
|
||||
|
||||
使用C++ WinAPI,龟速开发中……
|
||||
龟速开发中……
|
||||
|
||||
## 优缺点
|
||||
|
||||
- 所有操作,都是点击按钮内随机位置,且模拟泊松分布,不会像鼠标宏一样一直是同一个点,没有封号风险
|
||||
~~(虽然好像也没听说过谁用鼠标宏被封号的)~~
|
||||
- 模拟器窗口可以被遮挡,即使全屏看视频、玩游戏,也完全不影响辅助运行
|
||||
~~(但是模拟器还是不能最小化)~~
|
||||
- 使用C++ WinAPI开发,效率高,对系统性能占用小
|
||||
|
||||
## 使用说明
|
||||
|
||||
### alpha_2 版本
|
||||
|
||||
1. 使用蓝叠模拟器打开明日方舟,进入有**蓝色的开始行动按钮**的界面,勾上代理指挥
|
||||
2. 解压压缩包,**使用管理员权限**,打开"Test.exe"
|
||||
3. 目前只有最基本的功能,刷完体力+体力药就会自动停了……
|
||||
|
||||
## Todo
|
||||
|
||||
~~在做了在做了.jpg~~
|
||||
|
||||
- [ ] 图形化界面
|
||||
- [ ] 功能
|
||||
- [ ] 支持剿灭
|
||||
- [ ] 支持刷指定次数
|
||||
- [ ] 支持使模拟器窗口不可见
|
||||
- [x] 自动吃体力药
|
||||
- [ ] 自动吃石头(根据设置,指定数量)
|
||||
- [ ] 代理失败的情况
|
||||
- [ ] 支持更多模拟器
|
||||
- [ ] 支持等级提升
|
||||
- [ ] 支持凌晨4点更新数据
|
||||
- [ ] 信用访问
|
||||
- [ ] 基建收菜
|
||||
- [ ] 算法
|
||||
- [ ] 更换算法为找图,而不是当前的区域相似度对比
|
||||
|
||||
|
||||
## 致谢
|
||||
|
||||
感谢以下开源库/API
|
||||
|
||||
- WinAPI
|
||||
- OpenCV
|
||||
- MeoJson
|
||||
|
||||
160
Tools/Test/Test.vcxproj
Normal file
160
Tools/Test/Test.vcxproj
Normal file
@@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{36bc08f3-71cf-429a-ae69-291be8962cb2}</ProjectGuid>
|
||||
<RootNamespace>Test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)meojson\include;$(SolutionDir)MeoAssistance\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(TargetDir);$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(SolutionDir)meojson\include;$(SolutionDir)MeoAssistance\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(TargetDir);$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>MeoAssistance.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>MeoAssistance.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(TargetDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "Assistance.h"
|
||||
#include "Identify.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
2
meojson
2
meojson
Submodule meojson updated: 0a86b19d2a...6b854ac42b
BIN
resource/MissionSucceed.png
Normal file
BIN
resource/MissionSucceed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 842 KiB |
BIN
resource/PRTS.png
Normal file
BIN
resource/PRTS.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 811 KiB |
BIN
resource/StartButton1.png
Normal file
BIN
resource/StartButton1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 952 KiB |
BIN
resource/StartButton2.png
Normal file
BIN
resource/StartButton2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 988 KiB |
BIN
resource/UseMedicine.png
Normal file
BIN
resource/UseMedicine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 667 KiB |
BIN
resource/UseStone.png
Normal file
BIN
resource/UseStone.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 717 KiB |
112
resource/config.json
Normal file
112
resource/config.json
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"version": 0.1,
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"UseMedicine": {
|
||||
"viewRect": [
|
||||
571,
|
||||
118,
|
||||
621,
|
||||
504
|
||||
],
|
||||
"filename": "UseMedicine.png",
|
||||
"similarity": 0.999,
|
||||
"type": "click",
|
||||
"ctrlRect": [
|
||||
994,
|
||||
523,
|
||||
30,
|
||||
17
|
||||
]
|
||||
},
|
||||
"UseStone": {
|
||||
"viewRect": [
|
||||
571,
|
||||
118,
|
||||
621,
|
||||
504
|
||||
],
|
||||
"filename": "UseStone.png",
|
||||
"similarity": 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
|
||||
]
|
||||
},
|
||||
"StartButton2": {
|
||||
"viewRect": [
|
||||
966,
|
||||
386,
|
||||
126,
|
||||
259
|
||||
],
|
||||
"filename": "StartButton2.png",
|
||||
"similarity": 0.99,
|
||||
"type": "click",
|
||||
"ctrlRect": [
|
||||
975,
|
||||
353,
|
||||
97,
|
||||
230
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user