Compare commits
85 Commits
release.al
...
release.be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b885d722b1 | ||
|
|
4801cdf17d | ||
|
|
a496bb1fc8 | ||
|
|
ab5b4dd072 | ||
|
|
0908d0e381 | ||
|
|
2e16d76569 | ||
|
|
0b622e1313 | ||
|
|
ba104a0705 | ||
|
|
3c9f41ae4b | ||
|
|
8a08223ab9 | ||
|
|
47299fec45 | ||
|
|
b683ca52d5 | ||
|
|
b95f1f2dc9 | ||
|
|
423d538a80 | ||
|
|
eb6eb55161 | ||
|
|
a195f559b8 | ||
|
|
b5776d33b0 | ||
|
|
63aa3575c6 | ||
|
|
41f56a6e6b | ||
|
|
8e0430f773 | ||
|
|
94c81eb60f | ||
|
|
3eb0328630 | ||
|
|
78187cb9c7 | ||
|
|
d1826e8664 | ||
|
|
40b4751616 | ||
|
|
a01e50571b | ||
|
|
4b244b3aef | ||
|
|
e05430ec0e | ||
|
|
0a081d4fa2 | ||
|
|
a6488f0ea6 | ||
|
|
8844d35c2e | ||
|
|
0534e35871 | ||
|
|
107d3af5c5 | ||
|
|
1e170e6c1a | ||
|
|
f3773d22c6 | ||
|
|
7928a21051 | ||
|
|
2a89b01c1b | ||
|
|
d735404766 | ||
|
|
a8173eb82c | ||
|
|
67f52b321c | ||
|
|
6c3540b692 | ||
|
|
dd556817ea | ||
|
|
c393da2046 | ||
|
|
5657af6d94 | ||
|
|
f35ef18bd2 | ||
|
|
0fef8e2174 | ||
|
|
ee3afb440e | ||
|
|
952861c1e5 | ||
|
|
dab705a3de | ||
|
|
17f8353a97 | ||
|
|
53a1297842 | ||
|
|
e589a7498c | ||
|
|
ca412965ca | ||
|
|
adfed6d276 | ||
|
|
6fddf69e67 | ||
|
|
fb3cbb0b7a | ||
|
|
a348139df5 | ||
|
|
08db7f008d | ||
|
|
d66f178aec | ||
|
|
d51882fd1c | ||
|
|
c7b80b4603 | ||
|
|
1a0add784d | ||
|
|
70544e7809 | ||
|
|
3430be908b | ||
|
|
a617f254ff | ||
|
|
028f1ff182 | ||
|
|
41a3695556 | ||
|
|
9521285376 | ||
|
|
48125e241b | ||
|
|
91dad862f8 | ||
|
|
ff01ce3af4 | ||
|
|
b701a7ad99 | ||
|
|
96200d5ca6 | ||
|
|
0a89b1b48a | ||
|
|
11fa36aaaf | ||
|
|
78ad680067 | ||
|
|
30cea829f3 | ||
|
|
38bff9a43a | ||
|
|
f2e73a586d | ||
|
|
694dbcc02b | ||
|
|
bbdb1ce349 | ||
|
|
e684a1339a | ||
|
|
d17078e7b8 | ||
|
|
db65d51e37 | ||
|
|
43848c1e89 |
389
.gitignore
vendored
@@ -36,3 +36,392 @@ Release
|
||||
.vs
|
||||
*.vcxproj.user
|
||||
*.swp
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Nuget personal access tokens and Credentials
|
||||
nuget.config
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
@@ -13,45 +13,57 @@ EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Sanity", "Tools\Sanity\Sanity.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
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MeoAsstGui", "MeoAsstGui\MeoAsstGui.csproj", "{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300} = {362D1E30-F5AE-4279-9985-65C27B3BA300}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Screenshot", "Tools\Screenshot\Screenshot.vcxproj", "{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300} = {362D1E30-F5AE-4279-9985-65C27B3BA300}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{6C4B8D52-51D1-45F8-AAEC-808035443FD6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3rdPart", "3rdPart", "{402D9F27-234E-41A9-BEB1-1FC1FA3C8825}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Debug|x64.Build.0 = Debug|x64
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Debug|x86.Build.0 = Debug|Win32
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Release|x64.ActiveCfg = Release|x64
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Release|x64.Build.0 = Release|x64
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Release|x86.ActiveCfg = Release|Win32
|
||||
{362D1E30-F5AE-4279-9985-65C27B3BA300}.Release|x86.Build.0 = Release|Win32
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Debug|x64.Build.0 = Debug|x64
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD}.Release|x64.ActiveCfg = Release|x64
|
||||
{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
|
||||
{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}.Debug|x64.Build.0 = Debug|x64
|
||||
{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}.Release|x64.ActiveCfg = Release|x64
|
||||
{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{9CC7838E-D5FB-4771-848D-5F83D638C5AD} = {402D9F27-234E-41A9-BEB1-1FC1FA3C8825}
|
||||
{36BC08F3-71CF-429A-AE69-291BE8962CB2} = {6C4B8D52-51D1-45F8-AAEC-808035443FD6}
|
||||
{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B} = {6C4B8D52-51D1-45F8-AAEC-808035443FD6}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4F2C0E4B-4FE9-47C6-A878-6BD2FAD8B9B2}
|
||||
EndGlobalSection
|
||||
|
||||
@@ -19,16 +19,22 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\AsstDef.h" />
|
||||
<ClInclude Include="include\Assistance.h" />
|
||||
<ClInclude Include="include\AsstAux.h" />
|
||||
<ClInclude Include="include\AsstCaller.h" />
|
||||
<ClInclude Include="include\AsstDef.h" />
|
||||
<ClInclude Include="include\Configer.h" />
|
||||
<ClInclude Include="include\Identify.h" />
|
||||
<ClInclude Include="include\Logger.hpp" />
|
||||
<ClInclude Include="include\Updater.h" />
|
||||
<ClInclude Include="include\WinMacro.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Assistance.cpp" />
|
||||
<ClCompile Include="src\AsstCaller.cpp" />
|
||||
<ClCompile Include="src\Configer.cpp" />
|
||||
<ClCompile Include="src\Identify.cpp" />
|
||||
<ClCompile Include="src\Updater.cpp" />
|
||||
<ClCompile Include="src\WinMacro.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -100,7 +106,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)include;$(SolutionDir)meojson\include;$(OPENCV_PATH)\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(TargetDir);$(OPENCV_PATH)\x64\vc15\lib;$(LibraryPath)</LibraryPath>
|
||||
<LibraryPath>$(TargetDir);$(OPENCV_NEW_BUILD)lib\Release;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@@ -143,7 +149,7 @@
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world452d.lib;libmeojson.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>opencv_world452d.lib;libmeojson.lib;WinInet.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>$(TargetDir)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
@@ -175,7 +181,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opencv_world452.lib;libmeojson.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>opencv_core452.lib;opencv_imgcodecs452.lib;opencv_imgproc452.lib;WinInet.Lib;libmeojson.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
|
||||
<AdditionalLibraryDirectories>$(TargetDir)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
@@ -195,7 +201,7 @@
|
||||
</ImportGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties _1_1_4resource_4config_1json__JsonSchema="https://beaujs.com/schema.json" />
|
||||
<UserProperties _1_1_4resource_4config_1json__JsonSchema="" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -15,9 +15,6 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\Assistance.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Configer.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
@@ -30,11 +27,23 @@
|
||||
<ClInclude Include="include\AsstDef.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Assistance.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\AsstCaller.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Updater.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Logger.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\AsstAux.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Assistance.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Configer.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
@@ -44,6 +53,15 @@
|
||||
<ClCompile Include="src\WinMacro.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Assistance.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\AsstCaller.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Updater.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\resource\config.json">
|
||||
|
||||
@@ -5,8 +5,14 @@
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "AsstDef.h"
|
||||
#include "Configer.h"
|
||||
|
||||
namespace cv {
|
||||
class Mat;
|
||||
}
|
||||
|
||||
namespace asst {
|
||||
class WinMacro;
|
||||
@@ -18,25 +24,35 @@ namespace asst {
|
||||
Assistance();
|
||||
~Assistance();
|
||||
|
||||
std::optional<std::string> setSimulator(const std::string & simulator_name = std::string());
|
||||
void start();
|
||||
// void pause();
|
||||
void stop();
|
||||
std::optional<std::string> set_emulator(const std::string& emulator_name = std::string());
|
||||
|
||||
void start(const std::string& task);
|
||||
void stop(bool block = true);
|
||||
|
||||
bool set_param(const std::string& type, const std::string& param, const std::string& value);
|
||||
std::optional<std::string> get_param(const std::string& type, const std::string& param);
|
||||
|
||||
bool print_window(const std::string& filename, bool block = true);
|
||||
private:
|
||||
static void working_proc(Assistance* pThis);
|
||||
|
||||
// pair<scale, image>
|
||||
cv::Mat get_format_image(bool need_set_scale = true);
|
||||
|
||||
std::shared_ptr<WinMacro> m_pWindow = nullptr;
|
||||
std::shared_ptr<WinMacro> m_pView = nullptr;
|
||||
std::shared_ptr<WinMacro> m_pCtrl = nullptr;
|
||||
std::shared_ptr<Identify> m_Ider = nullptr;
|
||||
std::shared_ptr<Identify> m_pIder = nullptr;
|
||||
bool m_inited = false;
|
||||
|
||||
std::thread m_working_thread;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_condvar;
|
||||
bool m_thread_exit = false;
|
||||
bool m_thread_running = false;
|
||||
json::array m_next_tasks;
|
||||
std::vector<std::string> m_next_tasks;
|
||||
|
||||
Configer m_configer;
|
||||
};
|
||||
|
||||
}
|
||||
48
MeoAssistance/include/AsstAux.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace asst {
|
||||
|
||||
static std::string GetCurrentDir()
|
||||
{
|
||||
static std::string cur_dir;
|
||||
if (cur_dir.empty()) {
|
||||
char exepath_buff[_MAX_PATH] = { 0 };
|
||||
::GetModuleFileNameA(NULL, exepath_buff, _MAX_PATH);
|
||||
std::string exepath(exepath_buff);
|
||||
cur_dir = exepath.substr(0, exepath.find_last_of('\\') + 1);
|
||||
}
|
||||
return cur_dir;
|
||||
}
|
||||
|
||||
static std::string GetResourceDir()
|
||||
{
|
||||
static std::string res_dir = GetCurrentDir() + "resource\\";
|
||||
return res_dir;
|
||||
}
|
||||
|
||||
static std::string StringReplaceAll(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;
|
||||
}
|
||||
|
||||
static std::string GetFormatTimeString()
|
||||
{
|
||||
SYSTEMTIME curtime;
|
||||
GetLocalTime(&curtime);
|
||||
char buff[64] = { 0 };
|
||||
sprintf_s(buff, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
|
||||
curtime.wYear, curtime.wMonth, curtime.wDay,
|
||||
curtime.wHour, curtime.wMinute, curtime.wSecond, curtime.wMilliseconds);
|
||||
return buff;
|
||||
}
|
||||
}
|
||||
20
MeoAssistance/include/AsstCaller.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Assistance.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern __declspec(dllexport) asst::Assistance* CreateAsst();
|
||||
extern __declspec(dllexport) void DestoryAsst(asst::Assistance* p_asst);
|
||||
extern __declspec(dllexport) bool AsstCatchEmulator(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);
|
||||
extern __declspec(dllexport) bool CheckVersionUpdate(char * tag_buffer, int tag_bufsize, char * html_url_buffer, int html_bufsize, char * body_buffer, int body_bufsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,13 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "json_value.h"
|
||||
#include "json_array.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <process.h>
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
|
||||
namespace asst {
|
||||
|
||||
const static std::string Version = "release.beta.04";
|
||||
|
||||
enum class HandleType
|
||||
{
|
||||
Window = 1,
|
||||
@@ -15,6 +16,60 @@ namespace asst {
|
||||
Control = 4
|
||||
};
|
||||
|
||||
static std::ostream& operator<<(std::ostream& os, const HandleType& type)
|
||||
{
|
||||
static std::unordered_map<HandleType, std::string> _type_name = {
|
||||
{HandleType::Window, "Window"},
|
||||
{HandleType::View, "View"},
|
||||
{HandleType::Control, "Control"}
|
||||
};
|
||||
return os << _type_name.at(type);
|
||||
}
|
||||
|
||||
enum class TaskType {
|
||||
Invalid = 0,
|
||||
BasicClick = 1,
|
||||
DoNothing = 2,
|
||||
Stop = 4,
|
||||
PrintWindow,
|
||||
ClickSelf = 8 | BasicClick,
|
||||
ClickRect = 16 | BasicClick,
|
||||
ClickRand = 32 | BasicClick
|
||||
};
|
||||
static bool operator&(const TaskType& lhs, const TaskType& rhs)
|
||||
{
|
||||
return static_cast<std::underlying_type<TaskType>::type>(lhs) & static_cast<std::underlying_type<TaskType>::type>(rhs);
|
||||
}
|
||||
static std::ostream& operator<<(std::ostream& os, const TaskType& task)
|
||||
{
|
||||
static std::unordered_map<TaskType, std::string> _type_name = {
|
||||
{TaskType::Invalid, "Invalid"},
|
||||
{TaskType::BasicClick, "BasicClick"},
|
||||
{TaskType::ClickSelf, "ClickSelf"},
|
||||
{TaskType::ClickRect, "ClickRect"},
|
||||
{TaskType::ClickRand, "ClickRand"},
|
||||
{TaskType::DoNothing, "DoNothing"},
|
||||
{TaskType::Stop, "Stop"},
|
||||
{TaskType::PrintWindow, "PrintWindow"}
|
||||
};
|
||||
return os << _type_name.at(task);
|
||||
}
|
||||
|
||||
enum class AlgorithmType {
|
||||
JustReturn,
|
||||
MatchTemplate,
|
||||
CompareHist
|
||||
};
|
||||
static std::ostream& operator<<(std::ostream& os, const AlgorithmType& type)
|
||||
{
|
||||
static std::unordered_map<AlgorithmType, std::string> _type_name = {
|
||||
{AlgorithmType::JustReturn, "JustReturn"},
|
||||
{AlgorithmType::MatchTemplate, "MatchTemplate"},
|
||||
{AlgorithmType::CompareHist, "CompareHist"}
|
||||
};
|
||||
return os << _type_name.at(type);
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
Point() = default;
|
||||
@@ -32,10 +87,10 @@ namespace asst {
|
||||
{
|
||||
return { x, y, static_cast<int>(width * rhs), static_cast<int>(height * rhs) };
|
||||
}
|
||||
Rect center_zoom(double scale)
|
||||
Rect center_zoom(double scale) const
|
||||
{
|
||||
int half_width_scale = static_cast<int>(width * (1- scale) / 2) ;
|
||||
int half_hight_scale = static_cast<int>(height * (1 - scale) / 2) ;
|
||||
int half_width_scale = static_cast<int>(width * (1 - scale) / 2);
|
||||
int half_hight_scale = static_cast<int>(height * (1 - scale) / 2);
|
||||
return { x + half_width_scale, y + half_hight_scale, width - half_width_scale, height - half_hight_scale };
|
||||
}
|
||||
int x = 0;
|
||||
@@ -44,45 +99,58 @@ namespace asst {
|
||||
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());
|
||||
}
|
||||
struct HandleInfo {
|
||||
std::string class_name;
|
||||
std::string window_name;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
void DebugPrint(const std::string& level, Args &&... args)
|
||||
{
|
||||
static std::mutex trace_mutex;
|
||||
std::unique_lock<std::mutex> trace_lock(trace_mutex);
|
||||
struct AdbCmd {
|
||||
std::string path;
|
||||
std::string connect;
|
||||
std::string click;
|
||||
std::string display;
|
||||
std::string display_regex;
|
||||
int display_width = 0;
|
||||
int display_height = 0;
|
||||
};
|
||||
|
||||
SYSTEMTIME curtime;
|
||||
GetLocalTime(&curtime);
|
||||
printf("[%04d-%02d-%02d %02d:%02d:%02d.%03d][%s][Px%x][Tx%x] ",
|
||||
curtime.wYear, curtime.wMonth, curtime.wDay,
|
||||
curtime.wHour, curtime.wMinute, curtime.wSecond, curtime.wMilliseconds,
|
||||
level.c_str(), _getpid(), GetCurrentThreadId());
|
||||
printf(std::forward<Args>(args)...);
|
||||
printf("\n");
|
||||
}
|
||||
struct EmulatorInfo {
|
||||
std::string name;
|
||||
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 x_offset = 0;
|
||||
int y_offset = 0;
|
||||
int right_offset = 0;
|
||||
int bottom_offset = 0;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
inline void DebugTrace(Args &&... args)
|
||||
{
|
||||
//#ifdef _DEBUG
|
||||
DebugPrint("TRC", std::forward<Args>(args)...);
|
||||
//#endif
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void DebugTraceInfo(Args &&... args)
|
||||
{
|
||||
DebugPrint("INF", std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void DebugTraceError(Args &&... args)
|
||||
{
|
||||
DebugPrint("ERR", std::forward<Args>(args)...);
|
||||
}
|
||||
struct TaskInfo {
|
||||
std::string filename; // 图片文件名
|
||||
double threshold = 0; // 模板匹配阈值
|
||||
double cache_threshold = 0; // 直方图比较阈值
|
||||
TaskType type = TaskType::Invalid; // 任务类型
|
||||
std::vector<std::string> next; // 下一个可能的任务(列表)
|
||||
int exec_times = 0; // 任务已执行了多少次
|
||||
int max_times = INT_MAX; // 任务最多执行多少次
|
||||
std::vector<std::string> exceeded_next; // 达到最多次数了之后,下一个可能的任务(列表)
|
||||
std::vector<std::string> reduce_other_times; // 执行了该任务后,需要减少别的任务的执行次数。例如执行了吃理智药,则说明上一次点击蓝色开始行动按钮没生效,所以蓝色开始行动要-1
|
||||
asst::Rect specific_area; // 指定区域,目前仅针对ClickRect任务有用,会点这个区域
|
||||
int pre_delay = 0; // 执行该任务前的延时
|
||||
int rear_delay = 0; // 执行该任务后的延时
|
||||
};
|
||||
|
||||
struct Options {
|
||||
bool identify_cache = false; // 图像识别缓存功能:开启后可以大幅降低CPU消耗,但需要保证要识别的按钮每次的位置不会改变
|
||||
int identify_delay = 0; // 图像识别延时:越快操作越快,但会增加CPU消耗
|
||||
int control_delay_lower = 0; // 点击随机延时下限:每次点击操作会进行随机延时
|
||||
int control_delay_upper = 0; // 点击随机延时上限:每次点击操作会进行随机延时
|
||||
bool print_window = false; // 截图功能:开启后每次结算界面会截图到screenshot目录下
|
||||
int print_window_delay = 0; // 截图延时:每次到结算界面,掉落物品不是一次性出来的,有个动画,所以需要等一会再截图
|
||||
int print_window_crop_offset = 0; // 截图额外裁剪:再额外把边框裁减掉一圈,不然企鹅物流有可能识别不出来
|
||||
};
|
||||
}
|
||||
@@ -1,23 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "json_object.h"
|
||||
#include <unordered_map>
|
||||
#include <optional>
|
||||
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace asst {
|
||||
|
||||
class Configer
|
||||
{
|
||||
public:
|
||||
Configer() = default;
|
||||
~Configer() = default;
|
||||
|
||||
static bool reload();
|
||||
static std::string getCurDir();
|
||||
static std::string getResDir();
|
||||
static json::object tasksJson;
|
||||
static json::object handleJson;
|
||||
static json::object optionsJson;
|
||||
private:
|
||||
Configer() = default;
|
||||
Configer(const Configer& rhs);
|
||||
Configer(Configer&& rhs) noexcept;
|
||||
|
||||
bool reload(const std::string& filename);
|
||||
|
||||
bool set_param(const std::string& type, const std::string& param, const std::string& value);
|
||||
std::optional<std::string> get_param(const std::string& type, const std::string& param);
|
||||
|
||||
void clear_exec_times();
|
||||
|
||||
Configer& operator=(const Configer& rhs);
|
||||
Configer& operator=(Configer&& rhs) noexcept;
|
||||
|
||||
constexpr static int DefaultWindowWidth = 1280;
|
||||
constexpr static int DefaultWindowHeight = 720;
|
||||
constexpr static double DefaultThreshold = 0.9;
|
||||
constexpr static double DefaultCacheThreshold = 0.9;
|
||||
|
||||
std::string m_version;
|
||||
Options m_options;
|
||||
std::unordered_map<std::string, TaskInfo> m_tasks;
|
||||
std::unordered_map<std::string, EmulatorInfo> m_handles;
|
||||
|
||||
private:
|
||||
|
||||
static std::string m_curDir;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "AsstDef.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include "AsstDef.h"
|
||||
|
||||
|
||||
namespace asst {
|
||||
|
||||
@@ -17,25 +18,26 @@ namespace asst {
|
||||
Identify() = default;
|
||||
~Identify() = default;
|
||||
|
||||
void setUseCache(bool b) noexcept;
|
||||
bool addImage(const std::string& name, const std::string& path);
|
||||
void set_use_cache(bool b) noexcept;
|
||||
bool add_image(const std::string& name, const std::string& path);
|
||||
|
||||
// return tuple< algorithmType, suitability, scaled asst::rect>
|
||||
std::tuple<int, double, asst::Rect> findImage(const cv::Mat& image, const std::string& templ, double threshold = 0.99);
|
||||
std::tuple<AlgorithmType, double, asst::Rect> find_image(const cv::Mat& image, const std::string& templ, double threshold = 0.99);
|
||||
|
||||
void clear_cache();
|
||||
private:
|
||||
cv::Mat image2Hist(const cv::Mat& src);
|
||||
double imageHistComp(const cv::Mat& src, const cv::MatND& hist);
|
||||
asst::Rect cvRect2Rect(const cv::Rect& cvRect) {
|
||||
cv::Mat image_2_hist(const cv::Mat& src);
|
||||
double image_hist_comp(const cv::Mat& src, const cv::MatND& hist);
|
||||
static asst::Rect cvrect_2_rect(const cv::Rect& cvRect) {
|
||||
return asst::Rect(cvRect.x, cvRect.y, cvRect.width, cvRect.height);
|
||||
}
|
||||
|
||||
// return pair< suitability, raw opencv::point>
|
||||
std::pair<double, cv::Point> findImage(const cv::Mat& cur, const cv::Mat& templ);
|
||||
std::pair<double, cv::Point> find_image(const cv::Mat& cur, const cv::Mat& templ);
|
||||
|
||||
std::unordered_map<std::string, cv::Mat> m_matMap;
|
||||
std::unordered_map<std::string, cv::Mat> m_mat_map;
|
||||
bool m_use_cache = true;
|
||||
std::unordered_map<std::string, std::pair<cv::Rect, cv::Mat>> m_cacheMap;
|
||||
std::unordered_map<std::string, std::pair<cv::Rect, cv::Mat>> m_cache_map; // λÖá¢Ö±·½Í¼»º´æ
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
110
MeoAssistance/include/Logger.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <iostream>
|
||||
|
||||
#include "AsstAux.h"
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace asst {
|
||||
class Logger {
|
||||
public:
|
||||
~Logger() = default;
|
||||
|
||||
Logger(const Logger&) = delete;
|
||||
Logger(Logger&&) = delete;
|
||||
|
||||
static Logger& get_instance()
|
||||
{
|
||||
static Logger _unique_instance;
|
||||
return _unique_instance;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log_trace(Args &&... args)
|
||||
{
|
||||
log("TRC", std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void log_info(Args &&... args)
|
||||
{
|
||||
log("INF", std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void log_error(Args &&... args)
|
||||
{
|
||||
log("ERR", std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
Logger() {
|
||||
log_trace("-----------------------------");
|
||||
log_trace("MeoAssistance Process Start");
|
||||
log_trace("Version", Version);
|
||||
log_trace("Build DataTime", __DATE__, __TIME__);
|
||||
log_trace("Working Path", GetCurrentDir());
|
||||
log_trace("Resource Path", GetResourceDir());
|
||||
log_trace("-----------------------------");
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void log(const std::string& level, Args &&... args)
|
||||
{
|
||||
std::unique_lock<std::mutex> trace_lock(m_trace_mutex);
|
||||
|
||||
char buff[128] = { 0 };
|
||||
sprintf_s(buff, "[%s][%s][Px%x][Tx%x]",
|
||||
asst::GetFormatTimeString().c_str(),
|
||||
level.c_str(), _getpid(), ::GetCurrentThreadId());
|
||||
|
||||
if (level == "ERR" || level == "INF"
|
||||
#ifdef _DEBUG
|
||||
|| level == "TRC"
|
||||
#endif
|
||||
) {
|
||||
stream_args(std::cout, buff, std::forward<Args>(args)...);
|
||||
}
|
||||
std::ofstream out_stream(asst::GetCurrentDir() + "asst.log", std::ios::out | std::ios::app);
|
||||
stream_args(out_stream, buff, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
inline void stream_args(std::ostream& os, T&& first, Args && ...rest)
|
||||
{
|
||||
os << first << " ";
|
||||
stream_args(os, std::forward<Args>(rest)...);
|
||||
}
|
||||
|
||||
inline void stream_args(std::ostream& os)
|
||||
{
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
std::mutex m_trace_mutex;
|
||||
};
|
||||
|
||||
class LoggerAux {
|
||||
public:
|
||||
LoggerAux(const std::string& func_name)
|
||||
: m_func_name(func_name),
|
||||
m_start_time(std::chrono::system_clock::now())
|
||||
{
|
||||
Logger::get_instance().log_trace(m_func_name, " | enter");
|
||||
}
|
||||
~LoggerAux()
|
||||
{
|
||||
auto duration = std::chrono::system_clock::now() - m_start_time;
|
||||
Logger::get_instance().log_trace(m_func_name, " | leave,",
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(duration).count(), "ms");
|
||||
}
|
||||
private:
|
||||
std::string m_func_name;
|
||||
std::chrono::time_point<std::chrono::system_clock> m_start_time;
|
||||
};
|
||||
}
|
||||
|
||||
#define DebugTrace Logger::get_instance().log_trace
|
||||
#define DebugTraceInfo Logger::get_instance().log_info
|
||||
#define DebugTraceError Logger::get_instance().log_error
|
||||
#define DebugTraceFunction LoggerAux _func_aux(__FUNCTION__)
|
||||
39
MeoAssistance/include/Updater.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <mutex>
|
||||
|
||||
namespace asst {
|
||||
struct __declspec(dllexport) VersionInfo {
|
||||
std::string tag_name;
|
||||
std::string html_url;
|
||||
std::string down_url;
|
||||
std::string author_name;
|
||||
std::string created_time;
|
||||
std::string body;
|
||||
};
|
||||
|
||||
class __declspec(dllexport) Updater
|
||||
{
|
||||
static const std::string GithubReleaseLastestApiUrl;
|
||||
static const std::string GithubReleaseApiUrl;
|
||||
public:
|
||||
~Updater() = default;
|
||||
Updater(const Updater&) = delete;
|
||||
Updater(Updater&&) = delete;
|
||||
|
||||
static Updater& get_instance();
|
||||
|
||||
bool has_new_version();
|
||||
const VersionInfo & get_version_info() const noexcept;
|
||||
|
||||
private:
|
||||
Updater() = default;
|
||||
std::optional<std::string> request_github_api();
|
||||
|
||||
bool m_has_new_version = false;
|
||||
VersionInfo m_lastest_version;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
}
|
||||
@@ -2,16 +2,20 @@
|
||||
|
||||
#include <string>
|
||||
#include <random>
|
||||
#include <optional>
|
||||
#include <Windows.h>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include "AsstDef.h"
|
||||
|
||||
namespace cv {
|
||||
class Mat;
|
||||
}
|
||||
|
||||
namespace asst {
|
||||
class WinMacro
|
||||
{
|
||||
public:
|
||||
WinMacro(const std::string & simulator_name, HandleType type);
|
||||
WinMacro(const EmulatorInfo & info, HandleType type);
|
||||
~WinMacro() = default;
|
||||
|
||||
bool captured() const noexcept;
|
||||
@@ -20,20 +24,28 @@ namespace asst {
|
||||
bool showWindow();
|
||||
bool hideWindow();
|
||||
bool click(const Point & p);
|
||||
bool clickRange(const Rect & rect);
|
||||
bool click(const Rect & rect);
|
||||
void setControlScale(double scale);
|
||||
cv::Mat getImage(const Rect& rect);
|
||||
Rect getWindowRect();
|
||||
const EmulatorInfo& getEmulatorInfo() const noexcept { return m_emulator_info; }
|
||||
const HandleType& getHandleType() const noexcept { return m_handle_type; }
|
||||
|
||||
static double getScreenScale();
|
||||
private:
|
||||
bool findHandle();
|
||||
std::optional<std::string> callCmd(const std::string& cmd, bool use_pipe = true);
|
||||
|
||||
const std::string m_simulator_name;
|
||||
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::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;
|
||||
double m_control_scale = 1;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,149 +3,361 @@
|
||||
#include "WinMacro.h"
|
||||
#include "Configer.h"
|
||||
#include "Identify.h"
|
||||
#include "Logger.hpp"
|
||||
#include "AsstAux.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include <time.h>
|
||||
#include <filesystem>
|
||||
|
||||
using namespace asst;
|
||||
|
||||
Assistance::Assistance()
|
||||
{
|
||||
Configer::reload();
|
||||
DebugTraceFunction;
|
||||
|
||||
m_Ider = std::make_shared<Identify>();
|
||||
for (auto&& pair : Configer::tasksJson)
|
||||
m_configer.reload(GetResourceDir() + "config.json");
|
||||
|
||||
m_pIder = std::make_shared<Identify>();
|
||||
for (auto&& [name, info] : m_configer.m_tasks)
|
||||
{
|
||||
m_Ider->addImage(pair.first, Configer::getResDir() + pair.second["filename"].as_string());
|
||||
m_pIder->add_image(name, GetResourceDir() + info.filename);
|
||||
}
|
||||
m_Ider->setUseCache(Configer::optionsJson["cache"].as_boolean());
|
||||
m_pIder->set_use_cache(m_configer.m_options.identify_cache);
|
||||
|
||||
m_working_thread = std::thread(working_proc, this);
|
||||
|
||||
}
|
||||
|
||||
Assistance::~Assistance()
|
||||
{
|
||||
m_pWindow->showWindow();
|
||||
DebugTraceFunction;
|
||||
|
||||
//if (m_pWindow != nullptr) {
|
||||
// m_pWindow->showWindow();
|
||||
//}
|
||||
|
||||
m_thread_exit = true;
|
||||
m_thread_running = false;
|
||||
m_condvar.notify_one();
|
||||
m_condvar.notify_all();
|
||||
|
||||
if (m_working_thread.joinable()) {
|
||||
m_working_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> Assistance::setSimulator(const std::string& simulator_name)
|
||||
std::optional<std::string> Assistance::set_emulator(const std::string& emulator_name)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
|
||||
stop();
|
||||
|
||||
auto create_handles = [&](const std::string name) -> bool {
|
||||
m_pWindow = std::make_shared<WinMacro>(name, HandleType::Window);
|
||||
m_pView = std::make_shared<WinMacro>(name, HandleType::View);
|
||||
m_pCtrl = std::make_shared<WinMacro>(name, HandleType::Control);
|
||||
auto create_handles = [&](const EmulatorInfo& info) -> bool {
|
||||
m_pWindow = std::make_shared<WinMacro>(info, HandleType::Window);
|
||||
m_pView = std::make_shared<WinMacro>(info, HandleType::View);
|
||||
m_pCtrl = std::make_shared<WinMacro>(info, HandleType::Control);
|
||||
return m_pWindow->captured() && m_pView->captured() && m_pCtrl->captured();
|
||||
};
|
||||
|
||||
bool ret = false;
|
||||
std::string cor_name = simulator_name;
|
||||
std::string cor_name = emulator_name;
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
if (simulator_name.empty()) {
|
||||
for (auto&& [name, value] : Configer::handleJson)
|
||||
// 自动匹配模拟器,逐个找
|
||||
if (emulator_name.empty()) {
|
||||
for (auto&& [name, info] : m_configer.m_handles)
|
||||
{
|
||||
ret = create_handles(name);
|
||||
ret = create_handles(info);
|
||||
if (ret) {
|
||||
cor_name = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = create_handles(simulator_name);
|
||||
else { // 指定的模拟器
|
||||
ret = create_handles(m_configer.m_handles[emulator_name]);
|
||||
}
|
||||
if (ret && m_pWindow->resizeWindow()) {
|
||||
if (ret && m_pWindow->showWindow() && m_pWindow->resizeWindow()) {
|
||||
m_inited = true;
|
||||
return cor_name;
|
||||
}
|
||||
else {
|
||||
m_inited = false;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void Assistance::start()
|
||||
void Assistance::start(const std::string& task)
|
||||
{
|
||||
if (m_thread_running) {
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Start |", task);
|
||||
|
||||
|
||||
if (m_thread_running || !m_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_configer.clear_exec_times();
|
||||
|
||||
m_pIder->clear_cache();
|
||||
m_next_tasks.clear();
|
||||
m_next_tasks.emplace_back("Begin");
|
||||
m_next_tasks.emplace_back(task);
|
||||
m_thread_running = true;
|
||||
m_condvar.notify_one();
|
||||
}
|
||||
|
||||
void Assistance::stop()
|
||||
void Assistance::stop(bool block)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Stop |", block ? "block" : "non block");
|
||||
|
||||
std::unique_lock<std::mutex> lock;
|
||||
if (block) { // 外部调用
|
||||
lock = std::unique_lock<std::mutex>(m_mutex);
|
||||
m_configer.clear_exec_times();
|
||||
}
|
||||
m_thread_running = false;
|
||||
m_next_tasks.clear();
|
||||
m_pIder->clear_cache();
|
||||
}
|
||||
|
||||
bool Assistance::set_param(const std::string& type, const std::string& param, const std::string& value)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("SetParam |", type, param, value);
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return m_configer.set_param(type, param, value);
|
||||
}
|
||||
|
||||
std::optional<std::string> Assistance::get_param(const std::string& type, const std::string& param)
|
||||
{
|
||||
// DebugTraceFunction;
|
||||
if (type == "status") {
|
||||
if (param == "running") {
|
||||
return std::to_string(m_thread_running);
|
||||
}
|
||||
else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
return m_configer.get_param(type, param);
|
||||
}
|
||||
|
||||
bool asst::Assistance::print_window(const std::string& filename, bool block)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("print_window |", block ? "block" : "non block");
|
||||
|
||||
std::unique_lock<std::mutex> lock;
|
||||
if (block) { // 外部调用
|
||||
lock = std::unique_lock<std::mutex>(m_mutex);
|
||||
}
|
||||
|
||||
auto&& image = get_format_image();
|
||||
// 保存的截图额外再裁剪掉一圈,不然企鹅物流识别不出来
|
||||
int offset = m_configer.m_options.print_window_crop_offset;
|
||||
cv::Rect rect(offset, offset, image.cols - offset * 2, image.rows - offset * 2);
|
||||
bool ret = cv::imwrite(filename.c_str(), image(rect));
|
||||
|
||||
if (ret) {
|
||||
DebugTraceInfo("PrintWindow to", filename);
|
||||
}
|
||||
else {
|
||||
DebugTraceError("PrintWindow error", filename);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Assistance::working_proc(Assistance* pThis)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
|
||||
while (!pThis->m_thread_exit) {
|
||||
std::unique_lock<std::mutex> lock(pThis->m_mutex);
|
||||
if (pThis->m_thread_running) {
|
||||
auto curImg = pThis->m_pView->getImage(pThis->m_pView->getWindowRect());
|
||||
|
||||
auto&& cur_image = pThis->get_format_image();
|
||||
|
||||
if (cur_image.empty()) {
|
||||
DebugTraceError("Unable to capture window image!!!");
|
||||
pThis->stop(false);
|
||||
continue;
|
||||
}
|
||||
if (cur_image.rows < 100) {
|
||||
DebugTraceInfo("Window Could not be minimized!!!");
|
||||
pThis->m_pWindow->showWindow();
|
||||
pThis->m_condvar.wait_for(lock,
|
||||
std::chrono::milliseconds(pThis->m_configer.m_options.identify_delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string matched_task;
|
||||
Rect matched_rect;
|
||||
for (auto&& task_jstr : pThis->m_next_tasks) {
|
||||
std::string task_name = task_jstr.as_string();
|
||||
double threshold = Configer::tasksJson[task_name]["threshold"].as_double();
|
||||
auto&& [algorithm, value, rect] = pThis->m_Ider->findImage(curImg, task_name, threshold);
|
||||
DebugTrace("%-20s %f", task_name.c_str(), value);
|
||||
if ( algorithm == 0 ||
|
||||
(algorithm == 1 && value >= threshold)
|
||||
|| (algorithm == 2 && value >= 0.9999)) {
|
||||
// 逐个匹配当前可能的图像
|
||||
for (auto&& task_name : pThis->m_next_tasks) {
|
||||
|
||||
double threshold = pThis->m_configer.m_tasks[task_name].threshold;
|
||||
double cache_threshold = pThis->m_configer.m_tasks[task_name].cache_threshold;
|
||||
|
||||
auto&& [algorithm, value, rect] = pThis->m_pIder->find_image(cur_image, task_name, threshold);
|
||||
DebugTrace(task_name, "Type:", algorithm, "Value:", value);
|
||||
if (algorithm == AlgorithmType::JustReturn ||
|
||||
(algorithm == AlgorithmType::MatchTemplate && value >= threshold)
|
||||
|| (algorithm == AlgorithmType::CompareHist && value >= cache_threshold)) {
|
||||
matched_task = task_name;
|
||||
matched_rect = rect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行任务
|
||||
if (!matched_task.empty()) {
|
||||
auto task = Configer::tasksJson[matched_task].as_object();
|
||||
std::string opType = task["type"].as_string();
|
||||
DebugTraceInfo("Matched: %s, type: %s", matched_task.c_str(), opType.c_str());
|
||||
auto&& task = pThis->m_configer.m_tasks[matched_task];
|
||||
DebugTraceInfo("***Matched***", matched_task, "Type:", task.type);
|
||||
// 前置固定延时
|
||||
if (task.pre_delay > 0) {
|
||||
DebugTrace("PreDelay", task.pre_delay);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(task.pre_delay));
|
||||
bool cv_ret = pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(task.pre_delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
if (cv_ret) { continue; }
|
||||
}
|
||||
|
||||
if (opType == "clickSelf") {
|
||||
pThis->m_pCtrl->clickRange(matched_rect);
|
||||
if (task.max_times != INT_MAX) {
|
||||
DebugTrace("CurTimes:", task.exec_times, "MaxTimes:", task.max_times);
|
||||
}
|
||||
else if (opType == "clickRand") {
|
||||
pThis->m_pCtrl->clickRange(pThis->m_pCtrl->getWindowRect());
|
||||
}
|
||||
else if (opType == "doNothing") {
|
||||
// do nothing
|
||||
}
|
||||
else if (opType == "stop") {
|
||||
DebugTrace("opType == stop");
|
||||
pThis->m_thread_running = false;
|
||||
pThis->m_next_tasks.clear();
|
||||
continue;
|
||||
if (task.exec_times < task.max_times) {
|
||||
// 随机延时功能
|
||||
if ((task.type & TaskType::BasicClick)
|
||||
&& pThis->m_configer.m_options.control_delay_upper != 0) {
|
||||
static std::default_random_engine rand_engine(std::chrono::system_clock::now().time_since_epoch().count());
|
||||
static std::uniform_int_distribution<unsigned> rand_uni(pThis->m_configer.m_options.control_delay_lower, pThis->m_configer.m_options.control_delay_upper);
|
||||
int delay = rand_uni(rand_engine);
|
||||
DebugTraceInfo("Random Delay", delay, "ms");
|
||||
bool cv_ret = pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
if (cv_ret) { continue; }
|
||||
}
|
||||
if (!pThis->m_thread_running) {
|
||||
continue;
|
||||
}
|
||||
switch (task.type) {
|
||||
case TaskType::ClickRect:
|
||||
matched_rect = task.specific_area;
|
||||
[[fallthrough]];
|
||||
case TaskType::ClickSelf:
|
||||
pThis->m_pCtrl->click(matched_rect);
|
||||
break;
|
||||
case TaskType::ClickRand:
|
||||
pThis->m_pCtrl->click(pThis->m_pCtrl->getWindowRect());
|
||||
break;
|
||||
case TaskType::DoNothing:
|
||||
break;
|
||||
case TaskType::Stop:
|
||||
DebugTrace("TaskType is Stop");
|
||||
pThis->stop(false);
|
||||
continue;
|
||||
break;
|
||||
case TaskType::PrintWindow:
|
||||
if (pThis->m_configer.m_options.print_window) {
|
||||
// 每次到结算界面,掉落物品不是一次性出来的,有个动画,所以需要等一会再截图
|
||||
int print_delay = pThis->m_configer.m_options.print_window_delay;
|
||||
DebugTraceInfo("Ready to print window, delay", print_delay);
|
||||
pThis->m_condvar.wait_for(lock,
|
||||
std::chrono::milliseconds(print_delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
|
||||
std::string dirname = GetCurrentDir() + "screenshot\\";
|
||||
std::filesystem::create_directory(dirname);
|
||||
auto time_str = StringReplaceAll(StringReplaceAll(GetFormatTimeString(), " ", "_"), ":", "-");
|
||||
std::string filename = dirname + time_str + ".png";
|
||||
pThis->print_window(filename, false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugTraceError("Unknown option type:", task.type);
|
||||
break;
|
||||
}
|
||||
++task.exec_times;
|
||||
|
||||
// 减少其他任务的执行次数
|
||||
// 例如,进入吃理智药的界面了,相当于上一次点蓝色开始行动没生效
|
||||
// 所以要给蓝色开始行动的次数减一
|
||||
for (auto&& reduce : task.reduce_other_times) {
|
||||
--pThis->m_configer.m_tasks[reduce].exec_times;
|
||||
DebugTrace("Reduce exec times", reduce, pThis->m_configer.m_tasks[reduce].exec_times);
|
||||
}
|
||||
// 后置固定延时
|
||||
if (task.rear_delay > 0) {
|
||||
DebugTrace("RearDelay", task.rear_delay);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(task.rear_delay));
|
||||
auto cv_ret = pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(task.rear_delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
if (cv_ret) { continue; }
|
||||
}
|
||||
pThis->m_next_tasks = pThis->m_configer.m_tasks[matched_task].next;
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Unknow option type: %s", opType.c_str());
|
||||
DebugTraceInfo("Reached limit");
|
||||
pThis->m_next_tasks = pThis->m_configer.m_tasks[matched_task].exceeded_next;
|
||||
}
|
||||
|
||||
pThis->m_next_tasks = Configer::tasksJson[matched_task]["next"].as_array();
|
||||
DebugTrace("Next: %s", pThis->m_next_tasks.to_string().c_str());
|
||||
// 单纯为了打印日志。。感觉可以优化下
|
||||
std::string nexts_str;
|
||||
for (auto&& name : pThis->m_next_tasks) {
|
||||
nexts_str += name + " ,";
|
||||
}
|
||||
if (nexts_str.back() == ',') {
|
||||
nexts_str.pop_back();
|
||||
}
|
||||
DebugTrace("Next:", nexts_str);
|
||||
}
|
||||
pThis->m_condvar.wait_for(lock, std::chrono::milliseconds(Configer::optionsJson["delay"]["fixedTime"].as_integer()));
|
||||
|
||||
pThis->m_condvar.wait_for(lock,
|
||||
std::chrono::milliseconds(pThis->m_configer.m_options.identify_delay),
|
||||
[&]() -> bool { return !pThis->m_thread_running; });
|
||||
}
|
||||
else {
|
||||
pThis->m_condvar.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat asst::Assistance::get_format_image(bool need_set_scale)
|
||||
{
|
||||
auto&& raw_image = m_pView->getImage(m_pView->getWindowRect());
|
||||
if (raw_image.empty() || raw_image.rows < 100) {
|
||||
DebugTraceError("Window image error");
|
||||
return raw_image;
|
||||
}
|
||||
// 把模拟器边框的一圈裁剪掉
|
||||
auto&& window_info = m_pView->getEmulatorInfo();
|
||||
int x_offset = window_info.x_offset;
|
||||
int y_offset = window_info.y_offset;
|
||||
int width = raw_image.cols - x_offset - window_info.right_offset;
|
||||
int height = raw_image.rows - y_offset - window_info.bottom_offset;
|
||||
|
||||
cv::Mat cropped(raw_image, cv::Rect(x_offset, y_offset, width, height));
|
||||
|
||||
if (need_set_scale) {
|
||||
double scale_width = static_cast<double>(width) / m_configer.DefaultWindowWidth;
|
||||
double scale_height = static_cast<double>(height) / m_configer.DefaultWindowHeight;
|
||||
// 有些模拟器有可收缩的侧边,会增加宽度。
|
||||
// config.json中设置的是侧边展开后的offset
|
||||
// 如果用户把侧边收起来了,则有侧边的那头会额外裁剪掉一些,长度偏小
|
||||
// 所以按这里面长、宽里大的那个算,大的那边没侧边
|
||||
double scale = std::max(scale_width, scale_height);
|
||||
m_pCtrl->setControlScale(scale);
|
||||
}
|
||||
|
||||
//// 调整尺寸,与资源中截图的标准尺寸一致
|
||||
//cv::Mat dst;
|
||||
//cv::resize(cropped, dst, cv::Size(m_configer.DefaultWindowWidth, m_configer.DefaultWindowHeight));
|
||||
|
||||
return cropped;
|
||||
}
|
||||
86
MeoAssistance/src/AsstCaller.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#include "AsstCaller.h"
|
||||
#include "Updater.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
asst::Assistance* CreateAsst()
|
||||
{
|
||||
return new asst::Assistance();
|
||||
}
|
||||
|
||||
void DestoryAsst(asst::Assistance* p_asst)
|
||||
{
|
||||
if (p_asst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete p_asst;
|
||||
p_asst = NULL;
|
||||
}
|
||||
|
||||
bool AsstCatchEmulator(asst::Assistance* p_asst)
|
||||
{
|
||||
if (p_asst == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto ret = p_asst->set_emulator();
|
||||
if (ret) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AsstStart(asst::Assistance* p_asst, const char* task)
|
||||
{
|
||||
if (p_asst == NULL) {
|
||||
}
|
||||
|
||||
p_asst->start(task);
|
||||
}
|
||||
|
||||
void AsstStop(asst::Assistance* p_asst)
|
||||
{
|
||||
if (p_asst == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
p_asst->stop();
|
||||
}
|
||||
|
||||
bool AsstSetParam(asst::Assistance* p_asst, const char* type, const char* param, const char* value)
|
||||
{
|
||||
if (p_asst == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p_asst->set_param(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->get_param(type, param);
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
strcpy_s(buffer, buffer_size, ret.value().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CheckVersionUpdate(char* tag_buffer, int tag_bufsize, char* html_url_buffer, int html_bufsize, char* body_buffer, int body_bufsize)
|
||||
{
|
||||
bool ret = asst::Updater::get_instance().has_new_version();
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
auto && info = asst::Updater::get_instance().get_version_info();
|
||||
strcpy_s(tag_buffer, tag_bufsize, info.tag_name.c_str());
|
||||
strcpy_s(html_url_buffer, html_bufsize, info.html_url.c_str());
|
||||
strcpy_s(body_buffer, body_bufsize, info.body.c_str());
|
||||
return true;
|
||||
}
|
||||
@@ -2,21 +2,34 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <Windows.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "json.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
using namespace asst;
|
||||
|
||||
json::object Configer::tasksJson;
|
||||
json::object Configer::handleJson;
|
||||
json::object Configer::optionsJson;
|
||||
|
||||
std::string Configer::m_curDir;
|
||||
|
||||
bool Configer::reload()
|
||||
Configer::Configer(const Configer& rhs)
|
||||
: m_version(rhs.m_version),
|
||||
m_options(rhs.m_options),
|
||||
m_tasks(rhs.m_tasks),
|
||||
m_handles(rhs.m_handles)
|
||||
{
|
||||
std::string filename = getResDir() + "config.json";
|
||||
}
|
||||
|
||||
Configer::Configer(Configer&& rhs) noexcept
|
||||
: m_version(std::move(rhs.m_version)),
|
||||
m_options(std::move(rhs.m_options)),
|
||||
m_tasks(std::move(rhs.m_tasks)),
|
||||
m_handles(std::move(rhs.m_handles))
|
||||
{
|
||||
}
|
||||
|
||||
bool Configer::reload(const std::string& filename)
|
||||
{
|
||||
DebugTraceFunction;
|
||||
DebugTrace("Configer::reload | ", filename);
|
||||
|
||||
std::ifstream ifs(filename, std::ios::in);
|
||||
if (!ifs.is_open()) {
|
||||
return false;
|
||||
@@ -28,30 +41,240 @@ bool Configer::reload()
|
||||
|
||||
auto ret = json::parser::parse(content);
|
||||
if (!ret) {
|
||||
DebugTrace("parse error", content);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto root = std::move(ret).value();
|
||||
tasksJson = root["tasks"].as_object();
|
||||
handleJson = root["handle"].as_object();
|
||||
optionsJson = root["options"].as_object();
|
||||
|
||||
Configer temp;
|
||||
try {
|
||||
temp.m_version = root["version"].as_string();
|
||||
|
||||
auto options_obj = root["options"].as_object();
|
||||
{
|
||||
temp.m_options.identify_delay = options_obj["identifyDelay"].as_integer();
|
||||
temp.m_options.identify_cache = options_obj["identifyCache"].as_boolean();
|
||||
temp.m_options.control_delay_lower = options_obj["controlDelayRange"][0].as_integer();
|
||||
temp.m_options.control_delay_upper = options_obj["controlDelayRange"][1].as_integer();
|
||||
temp.m_options.print_window = options_obj["printWindow"].as_boolean();
|
||||
temp.m_options.print_window_delay = options_obj["printWindowDelay"].as_integer();
|
||||
temp.m_options.print_window_crop_offset = options_obj["printWindowCropOffset"].as_integer();
|
||||
}
|
||||
DebugTrace("Options", options_obj.to_string());
|
||||
|
||||
auto tasks_obj = root["tasks"].as_object();
|
||||
for (auto&& [name, task_json] : tasks_obj) {
|
||||
TaskInfo task_info;
|
||||
task_info.filename = task_json["filename"].as_string();
|
||||
if (task_json.exist("threshold")) {
|
||||
task_info.threshold = task_json["threshold"].as_double();
|
||||
}
|
||||
else {
|
||||
task_info.threshold = DefaultThreshold;
|
||||
}
|
||||
if (task_json.exist("cacheThreshold")) {
|
||||
task_info.cache_threshold = task_json["cacheThreshold"].as_double();
|
||||
}
|
||||
else {
|
||||
task_info.cache_threshold = DefaultCacheThreshold;
|
||||
}
|
||||
|
||||
std::string type = task_json["type"].as_string();
|
||||
std::transform(type.begin(), type.end(), type.begin(), std::tolower);
|
||||
if (type == "clickself") {
|
||||
task_info.type = TaskType::ClickSelf;
|
||||
}
|
||||
else if (type == "clickrand") {
|
||||
task_info.type = TaskType::ClickRand;
|
||||
}
|
||||
else if (type == "donothing" || type.empty()) {
|
||||
task_info.type = TaskType::DoNothing;
|
||||
}
|
||||
else if (type == "stop") {
|
||||
task_info.type = TaskType::Stop;
|
||||
}
|
||||
else if (type == "clickrect") {
|
||||
task_info.type = TaskType::ClickRect;
|
||||
auto area_json = task_json["specificArea"].as_array();
|
||||
task_info.specific_area = Rect(
|
||||
area_json[0].as_integer(),
|
||||
area_json[1].as_integer(),
|
||||
area_json[2].as_integer(),
|
||||
area_json[3].as_integer());
|
||||
}
|
||||
else if (type == "printwindow") {
|
||||
task_info.type = TaskType::PrintWindow;
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Task:", name, "error:", type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (task_json.exist("maxTimes")) {
|
||||
task_info.max_times = task_json["maxTimes"].as_integer();
|
||||
}
|
||||
if (task_json.exist("exceededNext")) {
|
||||
auto next_arr = task_json["exceededNext"].as_array();
|
||||
for (auto&& name : next_arr) {
|
||||
task_info.exceeded_next.emplace_back(name.as_string());
|
||||
}
|
||||
}
|
||||
else {
|
||||
task_info.exceeded_next.emplace_back("Stop");
|
||||
}
|
||||
if (task_json.exist("preDelay")) {
|
||||
task_info.pre_delay = task_json["preDelay"].as_integer();
|
||||
}
|
||||
if (task_json.exist("rearDelay")) {
|
||||
task_info.rear_delay = task_json["rearDelay"].as_integer();
|
||||
}
|
||||
if (task_json.exist("reduceOtherTimes")) {
|
||||
auto reduce_arr = task_json["reduceOtherTimes"].as_array();
|
||||
for (auto&& reduce : reduce_arr) {
|
||||
task_info.reduce_other_times.emplace_back(reduce.as_string());
|
||||
}
|
||||
}
|
||||
|
||||
auto next_arr = task_json["next"].as_array();
|
||||
for (auto&& name : next_arr) {
|
||||
task_info.next.emplace_back(name.as_string());
|
||||
}
|
||||
|
||||
temp.m_tasks.emplace(name, task_info);
|
||||
}
|
||||
|
||||
auto handle_obj = root["handle"].as_object();
|
||||
for (auto&& [name, emulator_json] : handle_obj) {
|
||||
EmulatorInfo emulator_info;
|
||||
emulator_info.name = name;
|
||||
|
||||
auto window_arr = emulator_json["window"].as_array();
|
||||
for (auto&& info : window_arr) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.window.emplace_back(handle_info);
|
||||
}
|
||||
auto view_arr = emulator_json["view"].as_array();
|
||||
for (auto&& info : view_arr) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.view.emplace_back(handle_info);
|
||||
}
|
||||
auto ctrl_arr = emulator_json["control"].as_array();
|
||||
for (auto&& info : ctrl_arr) {
|
||||
HandleInfo handle_info;
|
||||
handle_info.class_name = info["class"].as_string();
|
||||
handle_info.window_name = info["window"].as_string();
|
||||
emulator_info.control.emplace_back(handle_info);
|
||||
}
|
||||
if (emulator_json.exist("adb")) {
|
||||
emulator_info.is_adb = true;
|
||||
// meojson的bug,暂时没空修,先转个字符串
|
||||
emulator_info.adb.path = StringReplaceAll(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.display = emulator_json["adb"]["display"].as_string();
|
||||
emulator_info.adb.display_regex = emulator_json["adb"]["displayRegex"].as_string();
|
||||
}
|
||||
emulator_info.x_offset = emulator_json["xOffset"].as_integer();
|
||||
emulator_info.y_offset = emulator_json["yOffset"].as_integer();
|
||||
if (emulator_json.exist("rightOffset")) {
|
||||
emulator_info.right_offset = emulator_json["rightOffset"].as_integer();
|
||||
}
|
||||
if (emulator_json.exist("bottomOffset")) {
|
||||
emulator_info.bottom_offset = emulator_json["bottomOffset"].as_integer();
|
||||
}
|
||||
emulator_info.width = DefaultWindowWidth + emulator_info.x_offset + emulator_info.right_offset;
|
||||
emulator_info.height = DefaultWindowHeight + emulator_info.y_offset + emulator_info.bottom_offset;
|
||||
|
||||
temp.m_handles.emplace(name, emulator_info);
|
||||
}
|
||||
}
|
||||
catch (json::exception& e) {
|
||||
DebugTraceError("Load config json error!", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
*this = std::move(temp);
|
||||
DebugTrace("Load config succeed");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Configer::getCurDir()
|
||||
bool Configer::set_param(const std::string& type, const std::string& param, const std::string& value)
|
||||
{
|
||||
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);
|
||||
// 暂时只用到了这些,总的参数太多了,后面要用啥再加上
|
||||
if (type == "task.type") {
|
||||
if (m_tasks.find(param) == m_tasks.cend()) {
|
||||
return false;
|
||||
}
|
||||
auto& task_info = m_tasks[param];
|
||||
std::string type = value;
|
||||
std::transform(type.begin(), type.end(), type.begin(), std::tolower);
|
||||
if (type == "clickself") {
|
||||
task_info.type = TaskType::ClickSelf;
|
||||
}
|
||||
else if (type == "clickrand") {
|
||||
task_info.type = TaskType::ClickRand;
|
||||
}
|
||||
else if (type == "donothing" || type.empty()) {
|
||||
task_info.type = TaskType::DoNothing;
|
||||
}
|
||||
else if (type == "stop") {
|
||||
task_info.type = TaskType::Stop;
|
||||
}
|
||||
else if (type == "clickrect") {
|
||||
task_info.type = TaskType::ClickRect;
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Task", param, "'s type error:", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return m_curDir;
|
||||
else if (type == "task.maxTimes") {
|
||||
if (m_tasks.find(param) == m_tasks.cend()) {
|
||||
return false;
|
||||
}
|
||||
m_tasks[param].max_times = std::stoi(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string Configer::getResDir()
|
||||
std::optional<std::string> Configer::get_param(const std::string& type, const std::string& param)
|
||||
{
|
||||
return getCurDir() + "resource\\";
|
||||
// 暂时只用到了这些,总的参数太多了,后面要用啥再加上
|
||||
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::clear_exec_times()
|
||||
{
|
||||
for (auto&& t : m_tasks) {
|
||||
t.second.exec_times = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Configer& asst::Configer::operator=(const Configer& rhs)
|
||||
{
|
||||
m_version = rhs.m_version;
|
||||
m_options = rhs.m_options;
|
||||
m_tasks = rhs.m_tasks;
|
||||
m_handles = rhs.m_handles;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Configer& asst::Configer::operator=(Configer&& rhs) noexcept
|
||||
{
|
||||
m_version = std::move(rhs.m_version);
|
||||
m_options = std::move(rhs.m_options);
|
||||
m_tasks = std::move(rhs.m_tasks);
|
||||
m_handles = std::move(rhs.m_handles);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -6,28 +6,28 @@
|
||||
using namespace asst;
|
||||
using namespace cv;
|
||||
|
||||
bool Identify::addImage(const std::string& name, const std::string& path)
|
||||
bool Identify::add_image(const std::string& name, const std::string& path)
|
||||
{
|
||||
Mat mat = imread(path);
|
||||
if (mat.empty()) {
|
||||
return false;
|
||||
}
|
||||
m_matMap.emplace(name, mat);
|
||||
m_mat_map.emplace(name, mat);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Identify::setUseCache(bool b) noexcept
|
||||
void Identify::set_use_cache(bool b) noexcept
|
||||
{
|
||||
if (b) {
|
||||
m_use_cache = true;
|
||||
}
|
||||
else {
|
||||
m_cacheMap.clear();
|
||||
m_cache_map.clear();
|
||||
m_use_cache = false;
|
||||
}
|
||||
}
|
||||
|
||||
Mat Identify::image2Hist(const cv::Mat& src)
|
||||
Mat Identify::image_2_hist(const cv::Mat& src)
|
||||
{
|
||||
Mat src_hsv;
|
||||
cvtColor(src, src_hsv, COLOR_BGR2HSV);
|
||||
@@ -46,12 +46,13 @@ Mat Identify::image2Hist(const cv::Mat& src)
|
||||
return src_hist;
|
||||
}
|
||||
|
||||
double Identify::imageHistComp(const cv::Mat& src, const cv::MatND& hist)
|
||||
double Identify::image_hist_comp(const cv::Mat& src, const cv::MatND& hist)
|
||||
{
|
||||
return compareHist(image2Hist(src), hist, CV_COMP_CORREL);
|
||||
// keep the interface return value unchanged
|
||||
return 1 - compareHist(image_2_hist(src), hist, CV_COMP_BHATTACHARYYA);
|
||||
}
|
||||
|
||||
std::pair<double, cv::Point> Identify::findImage(const cv::Mat& image, const cv::Mat& templ)
|
||||
std::pair<double, cv::Point> Identify::find_image(const cv::Mat& image, const cv::Mat& templ)
|
||||
{
|
||||
Mat image_hsv;
|
||||
Mat templ_hsv;
|
||||
@@ -59,7 +60,7 @@ std::pair<double, cv::Point> Identify::findImage(const cv::Mat& image, const cv:
|
||||
cvtColor(templ, templ_hsv, COLOR_BGR2HSV);
|
||||
|
||||
Mat matched;
|
||||
matchTemplate(image_hsv, templ_hsv, matched, cv::TM_CCORR_NORMED);
|
||||
matchTemplate(image_hsv, templ_hsv, matched, cv::TM_CCOEFF_NORMED);
|
||||
|
||||
double minVal = 0, maxVal = 0;
|
||||
cv::Point minLoc, maxLoc;
|
||||
@@ -67,32 +68,36 @@ std::pair<double, cv::Point> Identify::findImage(const cv::Mat& image, const cv:
|
||||
return { maxVal, maxLoc };
|
||||
}
|
||||
|
||||
std::tuple<int, double, asst::Rect> Identify::findImage(const Mat& cur, const std::string& templ, double threshold)
|
||||
std::tuple<AlgorithmType, double, asst::Rect> Identify::find_image(const Mat& cur, const std::string& templ, double threshold)
|
||||
{
|
||||
if (m_matMap.find(templ) == m_matMap.cend()) {
|
||||
return { 0, 0, asst::Rect() };
|
||||
if (m_mat_map.find(templ) == m_mat_map.cend()) {
|
||||
return { AlgorithmType::JustReturn, 0, asst::Rect() };
|
||||
}
|
||||
|
||||
if (m_use_cache && m_cacheMap.find(templ) != m_cacheMap.cend()) {
|
||||
DebugTrace("Identify | %s get cache", templ.c_str());
|
||||
auto&& [rect, hist] = m_cacheMap.at(templ);
|
||||
double value = imageHistComp(cur(rect), hist);
|
||||
return { 2, value, cvRect2Rect(rect).center_zoom(0.8) };
|
||||
// 有缓存,用直方图比较,CPU占用会低很多,但要保证每次按钮图片的位置不变
|
||||
if (m_use_cache && m_cache_map.find(templ) != m_cache_map.cend()) {
|
||||
auto&& [rect, hist] = m_cache_map.at(templ);
|
||||
double value = image_hist_comp(cur(rect), hist);
|
||||
return { AlgorithmType::CompareHist, value, cvrect_2_rect(rect).center_zoom(0.8) };
|
||||
}
|
||||
else {
|
||||
auto&& templ_mat = m_matMap.at(templ);
|
||||
auto&& [value, point] = findImage(cur, templ_mat);
|
||||
else { // 没缓存就模板匹配
|
||||
auto&& templ_mat = m_mat_map.at(templ);
|
||||
auto&& [value, point] = find_image(cur, templ_mat);
|
||||
cv::Rect raw_rect(point.x, point.y, templ_mat.cols, templ_mat.rows);
|
||||
|
||||
|
||||
if (m_use_cache && value >= threshold) {
|
||||
DebugTrace("Identify | %s add to cache", templ.c_str());
|
||||
m_cacheMap.emplace(templ, std::make_pair(raw_rect, image2Hist(cur(raw_rect))));
|
||||
m_cache_map.emplace(templ, std::make_pair(raw_rect, image_2_hist(cur(raw_rect))));
|
||||
}
|
||||
|
||||
return { 1, value, cvRect2Rect(raw_rect).center_zoom(0.8) };
|
||||
return { AlgorithmType::MatchTemplate, value, cvrect_2_rect(raw_rect).center_zoom(0.8) };
|
||||
}
|
||||
}
|
||||
|
||||
void Identify::clear_cache()
|
||||
{
|
||||
m_cache_map.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
std::pair<double, asst::Rect> Identify::findImageWithFile(const cv::Mat& cur, const std::string& filename)
|
||||
{
|
||||
|
||||
98
MeoAssistance/src/Updater.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "Updater.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include <WinInet.h>
|
||||
|
||||
#include "json.h"
|
||||
#include "AsstDef.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
using namespace asst;
|
||||
|
||||
const std::string Updater::GithubReleaseLastestApiUrl = "https://api.github.com/repos/MistEO/MeoAssistance/releases/latest";
|
||||
const std::string Updater::GithubReleaseApiUrl = "https://api.github.com/repos/MistEO/MeoAssistance/releases/latest";
|
||||
|
||||
Updater& Updater::get_instance()
|
||||
{
|
||||
static Updater unique_instance;
|
||||
return unique_instance;
|
||||
}
|
||||
|
||||
bool Updater::has_new_version()
|
||||
{
|
||||
auto req_ret = request_github_api();
|
||||
if (!req_ret) {
|
||||
DebugTraceInfo("Requeset Error");
|
||||
return false;
|
||||
}
|
||||
auto parse_ret = json::parser::parse(req_ret.value());
|
||||
if (!parse_ret) {
|
||||
DebugTraceInfo("Parse Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
json::value root = std::move(parse_ret).value();
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
try {
|
||||
m_lastest_version.tag_name = root["tag_name"].as_string();
|
||||
m_lastest_version.html_url = root["html_url"].as_string();
|
||||
m_lastest_version.author_name = root["author"]["login"].as_string();
|
||||
m_lastest_version.created_time = root["created_at"].as_string();
|
||||
m_lastest_version.body = root["body"].as_string();
|
||||
|
||||
auto assets = root["assets"].as_array();
|
||||
if (assets.size() == 1) {
|
||||
m_lastest_version.down_url = assets[0]["browser_download_url"].as_string();
|
||||
}
|
||||
}
|
||||
catch (json::exception& exp) {
|
||||
DebugTraceError("Json Error", exp.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_lastest_version.tag_name > Version) {
|
||||
m_has_new_version = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const VersionInfo & Updater::get_version_info() const noexcept
|
||||
{
|
||||
return m_lastest_version;
|
||||
}
|
||||
|
||||
std::optional<std::string> Updater::request_github_api()
|
||||
{
|
||||
HINTERNET h_session = ::InternetOpenA("GithubRelease", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
if (h_session == NULL) {
|
||||
return std::nullopt;
|
||||
}
|
||||
HINTERNET h_http = ::InternetOpenUrlA(h_session, GithubReleaseLastestApiUrl.c_str(), NULL, 0, INTERNET_FLAG_DONT_CACHE, 0);
|
||||
if (h_http == NULL) {
|
||||
return std::nullopt;
|
||||
}
|
||||
std::string response;
|
||||
DWORD buff_size = 4096;
|
||||
char *buffer = new char[buff_size];
|
||||
DWORD number = 1;
|
||||
while (number > 0) {
|
||||
memset(buffer, 0, buff_size);
|
||||
InternetReadFile(h_http, buffer, buff_size, &number);
|
||||
if (number != 0) {
|
||||
response += std::string(buffer, number);
|
||||
}
|
||||
}
|
||||
delete[] buffer;
|
||||
buffer = NULL;
|
||||
InternetCloseHandle(h_http);
|
||||
h_http = NULL;
|
||||
InternetCloseHandle(h_session);
|
||||
h_session = NULL;
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -2,70 +2,71 @@
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WinUser.h>
|
||||
|
||||
#include "Configer.h"
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
#include "AsstDef.h"
|
||||
#include "Logger.hpp"
|
||||
#include "Configer.h"
|
||||
|
||||
using namespace asst;
|
||||
|
||||
WinMacro::WinMacro(const std::string& simulator_name, HandleType type)
|
||||
: m_simulator_name(simulator_name),
|
||||
WinMacro::WinMacro(const EmulatorInfo& info, HandleType type)
|
||||
: m_emulator_info(info),
|
||||
m_handle_type(type),
|
||||
m_rand_engine(time(NULL))
|
||||
m_rand_engine(std::chrono::system_clock::now().time_since_epoch().count())
|
||||
{
|
||||
findHandle();
|
||||
}
|
||||
|
||||
bool WinMacro::captured() const noexcept
|
||||
{
|
||||
return m_handle != NULL;
|
||||
return m_handle != NULL && ::IsWindow(m_handle);
|
||||
}
|
||||
|
||||
bool WinMacro::findHandle()
|
||||
{
|
||||
json::array handle_arr;
|
||||
json::value simulator_json = Configer::handleJson[m_simulator_name];
|
||||
std::vector<HandleInfo> handle_vec;
|
||||
switch (m_handle_type) {
|
||||
case HandleType::Window:
|
||||
m_width = simulator_json["Width"].as_integer();
|
||||
m_height = simulator_json["Height"].as_integer();
|
||||
handle_arr = simulator_json["Window"].as_array();
|
||||
m_width = m_emulator_info.width;
|
||||
m_height = m_emulator_info.height;
|
||||
handle_vec = m_emulator_info.window;
|
||||
break;
|
||||
case HandleType::View:
|
||||
handle_arr = simulator_json["View"].as_array();
|
||||
handle_vec = m_emulator_info.view;
|
||||
break;
|
||||
case HandleType::Control:
|
||||
m_xOffset = simulator_json["xOffset"].as_integer();
|
||||
m_yOffset = simulator_json["yOffset"].as_integer();
|
||||
handle_arr = simulator_json["Control"].as_array();
|
||||
m_is_adb = m_emulator_info.is_adb;
|
||||
//m_x_offset = m_emulator_info.x_offset;
|
||||
//m_y_offset = m_emulator_info.y_offset;
|
||||
handle_vec = m_emulator_info.control;
|
||||
break;
|
||||
default:
|
||||
DebugTraceError("Handle type error!: %d", m_handle_type);
|
||||
DebugTraceError("Handle type error!", m_handle_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_handle = NULL;
|
||||
for (auto&& obj : handle_arr)
|
||||
for (auto&& handle_info : handle_vec)
|
||||
{
|
||||
wchar_t* class_wbuff = NULL;
|
||||
std::string class_str = obj["class"].as_string();
|
||||
if (!class_str.empty()) {
|
||||
size_t class_len = (class_str.size() + 1) * 2;
|
||||
if (!handle_info.class_name.empty()) {
|
||||
size_t class_len = (handle_info.class_name.size() + 1) * 2;
|
||||
class_wbuff = new wchar_t[class_len];
|
||||
::MultiByteToWideChar(CP_UTF8, 0, class_str.c_str(), -1, class_wbuff, class_len);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, handle_info.class_name.c_str(), -1, class_wbuff, class_len);
|
||||
}
|
||||
wchar_t* window_wbuff = NULL;
|
||||
std::string window_str = obj["window"].as_string();
|
||||
if (!window_str.empty()) {
|
||||
size_t window_len = (window_str.size() + 1) * 2;
|
||||
if (!handle_info.window_name.empty()) {
|
||||
size_t window_len = (handle_info.window_name.size() + 1) * 2;
|
||||
window_wbuff = new wchar_t[window_len];
|
||||
memset(window_wbuff, 0, window_len);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, window_str.c_str(), -1, window_wbuff, window_len);
|
||||
::MultiByteToWideChar(CP_UTF8, 0, handle_info.window_name.c_str(), -1, window_wbuff, window_len);
|
||||
}
|
||||
|
||||
m_handle = ::FindWindowExW(m_handle, NULL, class_wbuff, window_wbuff);
|
||||
@@ -79,8 +80,43 @@ bool WinMacro::findHandle()
|
||||
window_wbuff = NULL;
|
||||
}
|
||||
}
|
||||
if (m_is_adb && m_handle != NULL) {
|
||||
|
||||
DebugTrace("Handle: 0x%x, Name: %s, Type: %d", m_handle, m_simulator_name.c_str(), m_handle_type);
|
||||
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 = '"' + StringReplaceAll(m_emulator_info.adb.path, "[EmulatorPath]", adb_dir) + '"';
|
||||
std::string connect_cmd = adb_dir + m_emulator_info.adb.connect;
|
||||
|
||||
if (!callCmd(connect_cmd)) {
|
||||
DebugTraceError("Connect Adb Error");
|
||||
return false;
|
||||
}
|
||||
auto display_ret = callCmd(adb_dir + m_emulator_info.adb.display);
|
||||
if (display_ret) {
|
||||
std::string pipe_str = std::move(display_ret).value();
|
||||
sscanf_s(pipe_str.c_str(), m_emulator_info.adb.display_regex.c_str(),
|
||||
&m_emulator_info.adb.display_width, &m_emulator_info.adb.display_height);
|
||||
}
|
||||
else {
|
||||
DebugTraceError("Get Display Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_click_cmd = adb_dir + m_emulator_info.adb.click;
|
||||
}
|
||||
DebugTrace("Handle:", m_handle, "Name:", m_emulator_info.name, "Type:", m_handle_type);
|
||||
|
||||
if (m_handle != NULL) {
|
||||
return true;
|
||||
@@ -90,13 +126,81 @@ bool WinMacro::findHandle()
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::string> asst::WinMacro::callCmd(const std::string& cmd, bool use_pipe)
|
||||
{
|
||||
// 初始化管道
|
||||
constexpr int PipeBuffSize = 1024;
|
||||
HANDLE pipe_read = NULL;
|
||||
HANDLE pipe_write = NULL;
|
||||
SECURITY_ATTRIBUTES sa_out_pipe;
|
||||
::ZeroMemory(&sa_out_pipe, sizeof(sa_out_pipe));
|
||||
sa_out_pipe.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa_out_pipe.lpSecurityDescriptor = NULL;
|
||||
sa_out_pipe.bInheritHandle = TRUE;
|
||||
BOOL pipe_ret = FALSE;
|
||||
if (use_pipe) {
|
||||
pipe_ret = ::CreatePipe(&pipe_read, &pipe_write, &sa_out_pipe, PipeBuffSize);
|
||||
DebugTrace("Create Pipe ret", pipe_ret);
|
||||
}
|
||||
|
||||
// 准备启动ADB进程
|
||||
STARTUPINFOA startup_info;
|
||||
PROCESS_INFORMATION process_info;
|
||||
ZeroMemory(&startup_info, sizeof(startup_info));
|
||||
ZeroMemory(&process_info, sizeof(process_info));
|
||||
startup_info.cb = sizeof(STARTUPINFO);
|
||||
startup_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||
startup_info.hStdOutput = pipe_write;
|
||||
startup_info.hStdError = pipe_write;
|
||||
startup_info.wShowWindow = SW_HIDE;
|
||||
|
||||
DWORD ret = -1;
|
||||
if (!::CreateProcessA(NULL, const_cast<LPSTR>(cmd.c_str()), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &startup_info, &process_info)) {
|
||||
DebugTraceError("Create process error");
|
||||
return std::nullopt;
|
||||
}
|
||||
::WaitForSingleObject(process_info.hProcess, 30000);
|
||||
|
||||
std::string pipe_str;
|
||||
if (use_pipe && pipe_ret) {
|
||||
DWORD read_num = 0;
|
||||
DWORD std_num = 0;
|
||||
if (::PeekNamedPipe(pipe_read, NULL, 0, NULL, &read_num, NULL) && read_num > 0) {
|
||||
char pipe_buffer[PipeBuffSize] = { 0 };
|
||||
::ReadFile(pipe_read, pipe_buffer, read_num, &std_num, NULL);
|
||||
pipe_str = std::string(pipe_buffer, std_num);
|
||||
}
|
||||
}
|
||||
|
||||
::GetExitCodeProcess(process_info.hProcess, &ret);
|
||||
|
||||
::CloseHandle(process_info.hProcess);
|
||||
::CloseHandle(process_info.hThread);
|
||||
DebugTrace("Call", cmd, "ret", ret);
|
||||
if (use_pipe) {
|
||||
DebugTrace("Pipe:", pipe_str);
|
||||
}
|
||||
|
||||
if (pipe_read != NULL) {
|
||||
::CloseHandle(pipe_read);
|
||||
}
|
||||
if (pipe_write != NULL) {
|
||||
::CloseHandle(pipe_write);
|
||||
}
|
||||
|
||||
return pipe_str;
|
||||
}
|
||||
|
||||
bool WinMacro::resizeWindow(int width, int height)
|
||||
{
|
||||
if (m_handle_type != HandleType::Window) {
|
||||
if (m_handle_type != HandleType::Window || !::IsWindow(m_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::MoveWindow(m_handle, 0, 0, width / getScreenScale(), height / getScreenScale(), true);
|
||||
RECT rect;
|
||||
bool ret = ::GetWindowRect(m_handle, &rect);
|
||||
|
||||
return ret && ::MoveWindow(m_handle, rect.left, rect.top, width / getScreenScale(), height / getScreenScale(), true);
|
||||
}
|
||||
|
||||
bool WinMacro::resizeWindow()
|
||||
@@ -106,16 +210,16 @@ bool WinMacro::resizeWindow()
|
||||
|
||||
bool WinMacro::showWindow()
|
||||
{
|
||||
if (m_handle_type != HandleType::Window) {
|
||||
if (m_handle_type != HandleType::Window || !::IsWindow(m_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ::ShowWindow(m_handle, SW_SHOW);
|
||||
return ::ShowWindow(m_handle, SW_RESTORE);
|
||||
}
|
||||
|
||||
bool WinMacro::hideWindow()
|
||||
{
|
||||
if (m_handle_type != HandleType::Window) {
|
||||
if (m_handle_type != HandleType::Window || !::IsWindow(m_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -158,26 +262,30 @@ double WinMacro::getScreenScale()
|
||||
|
||||
bool WinMacro::click(const Point& p)
|
||||
{
|
||||
if (m_handle_type != HandleType::Control) {
|
||||
if (m_handle_type != HandleType::Control || !::IsWindow(m_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int x = (p.x + m_xOffset) / getScreenScale();
|
||||
int y = (p.y + m_yOffset) / getScreenScale();
|
||||
int x = p.x * m_control_scale;
|
||||
int y = p.y * m_control_scale;
|
||||
DebugTrace("Click, raw:", p.x, p.y, "corr:", x, y);
|
||||
|
||||
DebugTrace("click, raw: %d, %d, cor: %d, %d", p.x, p.y, x, y);
|
||||
|
||||
LPARAM lparam = MAKELPARAM(x, y);
|
||||
|
||||
::SendMessage(m_handle, WM_LBUTTONDOWN, MK_LBUTTON, lparam);
|
||||
::SendMessage(m_handle, WM_LBUTTONUP, 0, lparam);
|
||||
|
||||
return true;
|
||||
if (m_is_adb) {
|
||||
std::string cur_cmd = StringReplaceAll(m_click_cmd, "[x]", std::to_string(x));
|
||||
cur_cmd = StringReplaceAll(cur_cmd, "[y]", std::to_string(y));
|
||||
return callCmd(cur_cmd, false).has_value();
|
||||
}
|
||||
else {
|
||||
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)
|
||||
bool WinMacro::click(const Rect& rect)
|
||||
{
|
||||
if (m_handle_type != HandleType::Control) {
|
||||
if (m_handle_type != HandleType::Control || !::IsWindow(m_handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -202,8 +310,21 @@ bool WinMacro::clickRange(const Rect& rect)
|
||||
return click({ x, y });
|
||||
}
|
||||
|
||||
void asst::WinMacro::setControlScale(double scale)
|
||||
{
|
||||
if (m_is_adb) {
|
||||
m_control_scale = scale * scale * m_emulator_info.adb.display_width / Configer::DefaultWindowWidth;
|
||||
}
|
||||
else {
|
||||
m_control_scale = scale / getScreenScale();
|
||||
}
|
||||
}
|
||||
|
||||
Rect WinMacro::getWindowRect()
|
||||
{
|
||||
if (!::IsWindow(m_handle)) {
|
||||
return Rect();
|
||||
}
|
||||
RECT rect;
|
||||
bool ret = ::GetWindowRect(m_handle, &rect);
|
||||
if (!ret) {
|
||||
@@ -216,7 +337,7 @@ Rect WinMacro::getWindowRect()
|
||||
|
||||
cv::Mat WinMacro::getImage(const Rect& rect)
|
||||
{
|
||||
if (m_handle_type != HandleType::View) {
|
||||
if (m_handle_type != HandleType::View || !::IsWindow(m_handle)) {
|
||||
return cv::Mat();
|
||||
}
|
||||
|
||||
@@ -241,10 +362,12 @@ cv::Mat WinMacro::getImage(const Rect& rect)
|
||||
DeleteDC(memDC);
|
||||
ReleaseDC(m_handle, pDC);
|
||||
|
||||
#ifdef _DEBUG
|
||||
std::string filename = Configer::getCurDir() + "\\test.bmp";
|
||||
cv::imwrite(filename, dst_mat);
|
||||
#endif
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
std::string filename = GetCurrentDir() + "\\print.bmp";
|
||||
cv::imwrite(filename, dst_mat);
|
||||
#endif
|
||||
*/
|
||||
|
||||
return dst_mat;
|
||||
}
|
||||
6
MeoAsstGui/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
9
MeoAsstGui/App.xaml
Normal file
@@ -0,0 +1,9 @@
|
||||
<Application x:Class="MeoAsstGui.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:MeoAsstGui"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
MeoAsstGui/App.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace MeoAsstGui
|
||||
{
|
||||
/// <summary>
|
||||
/// App.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
26
MeoAsstGui/MainWindow.xaml
Normal file
@@ -0,0 +1,26 @@
|
||||
<Window x:Class="MeoAsstGui.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:MeoAsstGui"
|
||||
mc:Ignorable="d"
|
||||
Title="Meo明日方舟辅助" Height="520" Width="410" Loaded="OnLoaded">
|
||||
<Grid>
|
||||
<CheckBox x:Name="checkBox_useMedicine" Content="吃理智药" HorizontalAlignment="Left" Margin="50,100,0,0" VerticalAlignment="Top" Checked="checkBox_useMedicine_Checked" Unchecked="checkBox_useMedicine_Checked" IsChecked="True"/>
|
||||
<CheckBox x:Name="checkBox_useStone" Content="吃石头" HorizontalAlignment="Left" Margin="50,150,0,0" VerticalAlignment="Top" Checked="checkBox_useStone_Checked" Unchecked="checkBox_useStone_Checked"/>
|
||||
<TextBox x:Name="textBox_useStone" HorizontalAlignment="Left" Height="23" Margin="112,148,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="47" TextChanged="textBox_useStone_TextChanged" InputMethod.IsInputMethodEnabled="False"/>
|
||||
<Label x:Name="label_stoneNumber" Content="颗" HorizontalAlignment="Left" Margin="164,144,0,0" VerticalAlignment="Top" RenderTransformOrigin="-5.771,-6.291"/>
|
||||
<Button x:Name="button_startSanity" Content="开始刷理智" HorizontalAlignment="Left" Margin="50,300,0,0" VerticalAlignment="Top" Width="120" Height="50" Click="button_Click_startSanity"/>
|
||||
<Button x:Name="button_stop" Content="停止" HorizontalAlignment="Left" Margin="50,380,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,300,0,0" VerticalAlignment="Top" Width="120" Height="50" Click="button_Click_visit"/>
|
||||
<Label x:Name="exec_times" Content="" HorizontalAlignment="Left" Margin="230,60,0,0" VerticalAlignment="Top"/>
|
||||
<Label x:Name="stone_times" Content="" HorizontalAlignment="Left" Margin="230,144,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.702,0.403"/>
|
||||
<CheckBox x:Name="checkBox_maxTimes" Content="指定次数" HorizontalAlignment="Left" Margin="50,200,0,0" VerticalAlignment="Top" Checked="checkBox_maxTimes_Checked" Unchecked="checkBox_maxTimes_Checked"/>
|
||||
<TextBox x:Name="textBox_maxTimes" HorizontalAlignment="Left" Height="23" Margin="124,198,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="47" TextChanged="textBox_maxTimes_TextChanged" InputMethod.IsInputMethodEnabled="False"/>
|
||||
<Label x:Name="label" Content="次" HorizontalAlignment="Left" Margin="176,193,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.397,-0.745"/>
|
||||
<CheckBox x:Name="checkBox_shutdown" Content="刷完自动关机" HorizontalAlignment="Left" Margin="50,250,0,0" VerticalAlignment="Top" Checked="checkBox_shutdown_Checked"/>
|
||||
<Label x:Name="label_status" Content="" HorizontalAlignment="Left" Margin="230,30,0,0" VerticalAlignment="Top"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
186
MeoAsstGui/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace MeoAsstGui
|
||||
{
|
||||
/// <summary>
|
||||
/// MainWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
[DllImport("MeoAssistance.dll")] static private extern IntPtr CreateAsst();
|
||||
[DllImport("MeoAssistance.dll")] static private extern void DestoryAsst(IntPtr ptr);
|
||||
[DllImport("MeoAssistance.dll")] static private extern bool AsstCatchEmulator(IntPtr ptr);
|
||||
[DllImport("MeoAssistance.dll")] static private extern void AsstStart(IntPtr ptr, string task);
|
||||
[DllImport("MeoAssistance.dll")] static private extern void AsstStop(IntPtr ptr);
|
||||
[DllImport("MeoAssistance.dll")] static private extern bool AsstSetParam(IntPtr p_asst, string type, string param, string value);
|
||||
[DllImport("MeoAssistance.dll")]
|
||||
static private extern bool AsstGetParam(
|
||||
IntPtr p_asst, string type, string param,
|
||||
[In, Out] StringBuilder lp_string, int buffer_size);
|
||||
|
||||
|
||||
private IntPtr p_asst;
|
||||
UpdateDialog updateDialog;
|
||||
private DispatcherTimer update_times = new DispatcherTimer();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
~MainWindow()
|
||||
{
|
||||
DestoryAsst(p_asst);
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
updateDialog = new UpdateDialog();
|
||||
updateDialog.CheckUpdateAndShowDialog();
|
||||
updateDialog.Close();
|
||||
|
||||
p_asst = CreateAsst();
|
||||
update_times.Tick += new EventHandler(updateExecTimes);
|
||||
update_times.Interval = TimeSpan.FromSeconds(1);
|
||||
}
|
||||
private void button_Click_startSanity(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool catched = AsstCatchEmulator(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 = "";
|
||||
stone_times.Content = "";
|
||||
label_status.Content = "";
|
||||
}
|
||||
|
||||
private void checkBox_useMedicine_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (checkBox_useMedicine.IsChecked == true)
|
||||
{
|
||||
AsstSetParam(p_asst, "task.type", "UseMedicine", "doNothing");
|
||||
}
|
||||
else
|
||||
{
|
||||
AsstSetParam(p_asst, "task.type", "UseMedicine", "stop");
|
||||
}
|
||||
}
|
||||
|
||||
private void textBox_useStone_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (checkBox_useStone.IsChecked == true)
|
||||
{
|
||||
String text = textBox_useStone.Text != String.Empty ? textBox_useStone.Text : "0";
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StoneConfirm", text);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBox_useStone_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (checkBox_useStone.IsChecked == true)
|
||||
{
|
||||
AsstSetParam(p_asst, "task.type", "UseStone", "doNothing");
|
||||
String text = textBox_useStone.Text != String.Empty ? textBox_useStone.Text : "0";
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StoneConfirm", text);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsstSetParam(p_asst, "task.type", "UseStone", "stop");
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StoneConfirm", "0");
|
||||
}
|
||||
}
|
||||
|
||||
private void button_Click_visit(object sender, RoutedEventArgs e)
|
||||
{
|
||||
bool catched = AsstCatchEmulator(p_asst);
|
||||
catch_status.Content = "捕获模拟器窗口:" + catched;
|
||||
AsstStart(p_asst, "VisitBegin");
|
||||
}
|
||||
|
||||
private void updateExecTimes(object sender, EventArgs e)
|
||||
{
|
||||
StringBuilder buff_start = new StringBuilder(16);
|
||||
AsstGetParam(p_asst, "task.execTimes", "StartButton2", buff_start, 16);
|
||||
exec_times.Content = "已开始行动 " + buff_start + " 次";
|
||||
|
||||
if (checkBox_useStone.IsChecked == true)
|
||||
{
|
||||
StringBuilder buff_stone = new StringBuilder(16);
|
||||
AsstGetParam(p_asst, "task.execTimes", "StoneConfirm", buff_stone, 16);
|
||||
stone_times.Content = "已碎石 " + buff_stone + " 个";
|
||||
}
|
||||
|
||||
|
||||
StringBuilder buff_running = new StringBuilder(4);
|
||||
AsstGetParam(p_asst, "status", "running", buff_running, 4);
|
||||
if (int.Parse(buff_running.ToString()) == 0)
|
||||
{
|
||||
update_times.Stop();
|
||||
label_status.Content = "已刷完,自动停止";
|
||||
if (checkBox_shutdown.IsChecked == true)
|
||||
{
|
||||
System.Diagnostics.Process.Start("shutdown.exe", "-s -t 60");
|
||||
|
||||
MessageBoxResult result = MessageBox.Show("已刷完,即将关机,是否取消?", "提示", MessageBoxButton.OK);
|
||||
if (result == MessageBoxResult.OK)
|
||||
{
|
||||
System.Diagnostics.Process.Start("shutdown.exe", "-a");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label_status.Content = "正在运行中……";
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBox_maxTimes_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (checkBox_maxTimes.IsChecked == true)
|
||||
{
|
||||
String text = textBox_maxTimes.Text != String.Empty ? textBox_maxTimes.Text : "0";
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StartButton1", text);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StartButton1", int.MaxValue.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private void textBox_maxTimes_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (checkBox_maxTimes.IsChecked == true)
|
||||
{
|
||||
String text = textBox_maxTimes.Text != String.Empty ? textBox_maxTimes.Text : "0";
|
||||
AsstSetParam(p_asst, "task.maxTimes", "StartButton1", text);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkBox_shutdown_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
146
MeoAsstGui/MeoAsstGui.csproj
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{FFDC8F49-8EAF-45BE-B0A8-7EF0DB9875A2}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>MeoAsstGui</RootNamespace>
|
||||
<AssemblyName>MeoAsstGui</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>0.4.0.0</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>Always</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="WindowsBase" />
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="UpdateDialog.xaml.cs">
|
||||
<DependentUpon>UpdateDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="MainWindow.xaml.cs">
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="UpdateDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 和 x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="favicon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>xcopy /e /y /i $(SolutionDir)resource $(TargetDir)resource</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
55
MeoAsstGui/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("MeoAsstGui")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MeoAsstGui")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
//若要开始生成可本地化的应用程序,请设置
|
||||
//.csproj 文件中的 <UICulture>CultureYouAreCodingWith</UICulture>
|
||||
//例如,如果您在源文件中使用的是美国英语,
|
||||
//使用的是美国英语,请将 <UICulture> 设置为 en-US。 然后取消
|
||||
//对以下 NeutralResourceLanguage 特性的注释。 更新
|
||||
//以下行中的“en-US”以匹配项目文件中的 UICulture 设置。
|
||||
|
||||
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //主题特定资源词典所处位置
|
||||
//(未在页面中找到资源时使用,
|
||||
//或应用程序资源字典中找到时使用)
|
||||
ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置
|
||||
//(未在页面中找到资源时使用,
|
||||
//、应用程序或任何主题专用资源字典中找到时使用)
|
||||
)]
|
||||
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
70
MeoAsstGui/Properties/Resources.Designer.cs
generated
Normal file
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace MeoAsstGui.Properties
|
||||
{
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MeoAsstGui.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
MeoAsstGui/Properties/Resources.resx
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
29
MeoAsstGui/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace MeoAsstGui.Properties
|
||||
{
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
MeoAsstGui/Properties/Settings.settings
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
16
MeoAsstGui/UpdateDialog.xaml
Normal file
@@ -0,0 +1,16 @@
|
||||
<Window x:Class="MeoAsstGui.UpdateDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:MeoAsstGui"
|
||||
mc:Ignorable="d"
|
||||
Title="有新版本" Height="500" Width="400">
|
||||
<Grid>
|
||||
<Label x:Name="label_tag" Content="" HorizontalAlignment="Center" Margin="10,25,10.333,0" VerticalAlignment="Top" Height="50" Width="373" FontSize="24"/>
|
||||
<Label x:Name="label_body" Content="" HorizontalAlignment="Left" Margin="50,80,-656.667,0" VerticalAlignment="Top" Height="281" Width="1000" FontSize="16"/>
|
||||
<Button x:Name="button_confirm" Content="前往下载" HorizontalAlignment="Left" Margin="50,366,0,0" VerticalAlignment="Top" Width="120" Height="60" Click="button_confirm_Click"/>
|
||||
<Button x:Name="button_cancer" Content="下次一定" HorizontalAlignment="Left" Margin="220,366,0,0" VerticalAlignment="Top" Width="120" Height="60" Click="button_cancer_Click"/>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
69
MeoAsstGui/UpdateDialog.xaml.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace MeoAsstGui
|
||||
{
|
||||
/// <summary>
|
||||
/// UpdateDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class UpdateDialog : Window
|
||||
{
|
||||
[DllImport("MeoAssistance.dll")]
|
||||
static private extern bool CheckVersionUpdate(
|
||||
[In, Out] StringBuilder tag, int tag_bufsize,
|
||||
[In, Out] StringBuilder html_url, int html_bufsize,
|
||||
[In, Out] StringBuilder body, int body_bufsize);
|
||||
public UpdateDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private String m_htmlUrl;
|
||||
|
||||
public void CheckUpdateAndShowDialog()
|
||||
{
|
||||
StringBuilder tag = new StringBuilder(64);
|
||||
StringBuilder html_url = new StringBuilder(512);
|
||||
StringBuilder body = new StringBuilder(4096);
|
||||
|
||||
bool ret = CheckVersionUpdate(tag, 64, html_url, 512, body, 4096);
|
||||
if (!ret)
|
||||
{
|
||||
return;
|
||||
}
|
||||
label_tag.Content = "新版本:" + tag;
|
||||
byte[] buffer1 = Encoding.Default.GetBytes(body.ToString());
|
||||
byte[] buffer2 = Encoding.Convert(Encoding.UTF8, Encoding.Default, buffer1, 0, buffer1.Length);
|
||||
string strBuffer = Encoding.Default.GetString(buffer2, 0, buffer2.Length);
|
||||
strBuffer = strBuffer.Replace("\\r\\n", "\r\n");
|
||||
int len = strBuffer.Length > 128 ? 128 : strBuffer.Length;
|
||||
label_body.Content = strBuffer.Substring(0, len) + "\n......";
|
||||
|
||||
m_htmlUrl = html_url.ToString();
|
||||
ShowDialog();
|
||||
}
|
||||
|
||||
private void button_cancer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void button_confirm_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start(m_htmlUrl);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
MeoAsstGui/favicon.ico
Normal file
|
After Width: | Height: | Size: 66 KiB |
109
README.md
@@ -4,49 +4,95 @@ A game assistance for Arknights
|
||||
|
||||
一款明日方舟的游戏辅助,供PC端安卓模拟器使用,龟速开发中……
|
||||
|
||||

|
||||
|
||||
## 功能介绍
|
||||
|
||||
- 目前版本支持自动刷完所有体力+自动吃完体力药
|
||||
- 刷完后程序会自动停止
|
||||
- 代理失败会自动放弃本次行动
|
||||
- 所有操作,都是点击按钮内随机位置,且模拟泊松分布,不会像鼠标宏一样一直是同一个点,没有封号风险
|
||||
~~(虽然好像也没听说过谁用鼠标宏被封号的)~~
|
||||
- 模拟器窗口可以被遮挡,即使全屏看视频、玩游戏,也完全不影响辅助运行
|
||||
~~(但是模拟器还是不能最小化)~~
|
||||
- 自动刷理智
|
||||
- 可设置是否吃完理智药
|
||||
- 可设置是否吃石头以及数量
|
||||
- 可设置刷的次数(可以用来刷剿灭)
|
||||
- 可设置刷完自动关机
|
||||
- 支持剿灭模式
|
||||
- 支持打完升级了的情况
|
||||
- 支持代理失败的情况,会自动放弃本次行动
|
||||
- 支持每次刷完自动截图,可用于上传企鹅物流~
|
||||
- 自动访问好友基建
|
||||
- 访问完了还会贴心的帮你点进信用商店~
|
||||
- 其他优势
|
||||
- 所有操作,都是点击按钮内随机位置,且支持设置随机延时,没有封号风险
|
||||
- 模拟器窗口可以被遮挡,即使全屏看视频、玩游戏,也不影响辅助运行(但模拟器窗口不能最小化)
|
||||
- 支持多款主流模拟器
|
||||
- 自适应分辨率及屏幕缩放
|
||||
- 未来更多功能见[Todo](#Todo)
|
||||
|
||||
### 模拟器支持
|
||||
|
||||
#### 蓝叠模拟器
|
||||
|
||||
完美兼容,作者绝大部分测试均在蓝叠上进行,稳定性最能保障
|
||||
完美支持,作者绝大部分测试均在蓝叠上进行,稳定性最能保障
|
||||
|
||||
#### MuMu模拟器
|
||||
|
||||
完美支持,专门单独做了一套基于adb的控制逻辑。需要关闭模拟器的底部工具栏(快捷键Alt+T)
|
||||
|
||||
#### MuMu手游助手(星云引擎)
|
||||
|
||||
不支持,MuMu不响应SendMessage鼠标消息,而且这个版本不支持adb控制,正在想办法……
|
||||
|
||||
#### 逍遥模拟器
|
||||
|
||||
完美兼容
|
||||
支持,需要收起右侧侧边栏后使用,未多做测试
|
||||
|
||||
#### 雷电模拟器
|
||||
|
||||
完美兼容,需要收起右侧侧边栏后使用
|
||||
支持,需要收起右侧侧边栏后使用,未多做测试
|
||||
|
||||
#### 夜神模拟器
|
||||
|
||||
兼容,但辅助开始后不可操作模拟器窗口
|
||||
支持,效果不太好,且辅助开始后不可移动模拟器窗口,不推荐使用
|
||||
|
||||
#### 腾讯手游助手
|
||||
|
||||
兼容,但需要手动设置分辨率:设置中心——引擎设置——分辨率设置——1280x720——保存后重启模拟器
|
||||
不支持,腾讯不支持句柄的窗口尺寸调节,有人需要的话再单独做
|
||||
|
||||
#### MuMu手游助手 && MuMu模拟器
|
||||
#### 其他
|
||||
|
||||
不兼容,MuMu所有的窗口句柄均不响应SendMessage鼠标消息,但官方提供了adb的方式进行控制,有时间再做
|
||||
若需要使用其他模拟器、或上述不兼容的模拟器。欢迎给我提[ISSUE](https://github.com/MistEO/MeoAssistance/issues),会根据情况尽量适配~
|
||||
|
||||
## 使用说明
|
||||
|
||||
1. 使用蓝叠模拟器打开明日方舟,进入有**蓝色的开始行动按钮**的界面,勾上代理指挥
|
||||
2. 解压压缩包,**使用管理员权限**,打开"Sanity.exe"
|
||||
3. 目前只有最基本的功能,刷完体力+体力药就会自动停了……
|
||||
### 基本说明
|
||||
|
||||
1. 使用支持的模拟器打开明日方舟
|
||||
2. 解压压缩包,**使用管理员权限**,打开"MeoAsstGui.exe"
|
||||
3. 注意:运行期间,模拟器窗口可以被遮挡,全屏玩游戏、看视频等,完全不影响,但是模拟器不能最小化
|
||||
|
||||
### 刷理智
|
||||
|
||||
1. 明日方舟打开**蓝色开始按钮**的界面
|
||||
2. 根据你的需要勾选"吃理智药"和"吃石头"
|
||||
3. 点击"开始刷理智",开始后上面的选项也可以随时修改
|
||||
4. 刷完了会自动停止的
|
||||
|
||||
### 访问好友基建
|
||||
|
||||
1. 明日方舟处于任意界面均可,会自动帮你点过去
|
||||
2. 点击"访问基建"
|
||||
3. 达到10次上限,或者所有可访问的好友都访问完了,就会自动停的
|
||||
4. 然后会贴心的帮你跳转到信用商店,顺便收了当天信用~
|
||||
|
||||
### 设置操作延时
|
||||
|
||||
请手动修改`resource\config.json`文件中,`options`.`controlDelayRange`字段的值,格式为`[最小延时, 最大延时]`,单位为毫秒,例如想设置3~5秒的随机延时,即设置为`[ 3000, 5000]` 即可。文件保存后请重新打开程序。
|
||||
|
||||

|
||||
|
||||
### 自动截图功能
|
||||
|
||||
每次刷完结算界面,会自动截一张图,保存在`screenshot`文件夹中
|
||||
这个功能默认是打开的,不需要的话可以手动关掉:请手动修改`resource\config.json`文件中,`options`.`printWindow`字段的值,`true`是打开,`false`是关闭。文件保存后请重新打开程序。
|
||||

|
||||
|
||||
## Todo
|
||||
|
||||
@@ -54,33 +100,48 @@ A game assistance for Arknights
|
||||
|
||||
- [ ] 功能
|
||||
- [ ] 图形化界面
|
||||
- [x] 基本图形化界面
|
||||
- [ ] 图形化界面进一步完善
|
||||
- [ ] 日志打印,错误提示
|
||||
- [x] 刷完自动关机功能
|
||||
- [ ] ~~操作随机延时支持设置~~
|
||||
- [ ] 刷理智
|
||||
- [x] 支持剿灭
|
||||
- [ ] 支持刷指定次数
|
||||
- [x] 支持使模拟器窗口不可见
|
||||
- [x] 自动吃体力药
|
||||
- [ ] 自动吃石头(根据设置,指定数量)
|
||||
- [x] 代理失败的情况
|
||||
- [x] 支持等级提升
|
||||
- [x] 支持自动勾选代理指挥
|
||||
- [x] 支持刷指定次数
|
||||
- [x] 自动吃石头(根据设置,指定数量)
|
||||
- [x] 操作随机延时
|
||||
- [ ] 指定刷XX个某材料
|
||||
- [ ] 支持凌晨4点更新数据
|
||||
- [ ] 结束界面自动截图,可用于上传企鹅物流
|
||||
- [x] 结束界面自动截图,可用于上传企鹅物流
|
||||
- [ ] 持续监视理智,一有就自动刷掉
|
||||
- [x] 模拟器被最小化了,给出提示
|
||||
- [x] 支持更多模拟器
|
||||
- [ ] 信用访问
|
||||
- [x] 信用访问
|
||||
- [ ] 基建收菜
|
||||
- [ ] 当前公招可能干员一览
|
||||
- [x] 算法
|
||||
- [x] 更换算法为模板匹配找图,而不是当前的区域相似度对比
|
||||
- [x] 优化算法效率,添加缓存功能
|
||||
- [x] 优化任务队列,减少不必要的计算
|
||||
- [ ] 其他
|
||||
- [ ] 尝试减小程序体积
|
||||
- [ ] 掉落材料计数
|
||||
- [ ] 窗口分辨率自适应,针对MuMu、腾讯模拟器进一步适配
|
||||
- [ ] 进一步优化任务队列效率
|
||||
- [x] 其他
|
||||
- [x] 尝试减小程序体积
|
||||
- [x] 检查程序更新
|
||||
- [ ] 程序自动更新
|
||||
|
||||
|
||||
## 致谢
|
||||
|
||||
感谢以下开源库/API
|
||||
感谢以下开源库/免费API
|
||||
|
||||
- WinAPI
|
||||
- OpenCV
|
||||
- MeoJson
|
||||
- WPF
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{36bc08f3-71cf-429a-ae69-291be8962cb2}</ProjectGuid>
|
||||
<RootNamespace>Test</RootNamespace>
|
||||
<RootNamespace>Tools</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Sanity</ProjectName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
#include "Assistance.h"
|
||||
#include "Updater.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace asst;
|
||||
|
||||
bool up = Updater::get_instance().has_new_version();
|
||||
if (up) {
|
||||
auto && info = Updater::get_instance().get_version_info();
|
||||
std::cout << "ÓÐа汾£º" << info.tag_name << std::endl;
|
||||
std::cout << "µØÖ·£º" << info.html_url << std::endl;
|
||||
}
|
||||
|
||||
Assistance asst;
|
||||
|
||||
auto ret = asst.setSimulator();
|
||||
auto ret = asst.set_emulator();
|
||||
if (!ret) {
|
||||
DebugTraceError("Can't Find Simulator or Permission denied.");
|
||||
DebugTraceError("Can't Find Emulator or Permission denied.");
|
||||
getchar();
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
DebugTraceInfo("Find Simulator: %s", ret->c_str());
|
||||
DebugTraceInfo("Find Emulator:", ret.value());
|
||||
}
|
||||
|
||||
DebugTraceInfo("Start");
|
||||
asst.start();
|
||||
asst.start("SanityBegin");
|
||||
|
||||
getchar();
|
||||
|
||||
|
||||
161
Tools/Screenshot/Screenshot.vcxproj
Normal file
@@ -0,0 +1,161 @@
|
||||
<?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>{4AC1CFFF-D7B8-4FDA-BCFD-E4754275979B}</ProjectGuid>
|
||||
<RootNamespace>Tools</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Screenshot</ProjectName>
|
||||
</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>
|
||||
22
Tools/Screenshot/Screenshot.vcxproj.filters
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
30
Tools/Screenshot/main.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "Assistance.h"
|
||||
#include "AsstAux.h"
|
||||
#include "Logger.hpp"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace asst;
|
||||
|
||||
Assistance asst;
|
||||
|
||||
auto ret = asst.set_emulator();
|
||||
if (!ret) {
|
||||
DebugTraceError("Can't Find Emulator or Permission denied.");
|
||||
getchar();
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
DebugTraceInfo("Find Emulator:", ret.value());
|
||||
}
|
||||
|
||||
char ch = 0;
|
||||
while (ch != EOF) {
|
||||
ch = getchar();
|
||||
auto time_str = StringReplaceAll(StringReplaceAll(GetFormatTimeString(), " ", "_"), ":", "-");
|
||||
std::string filename = GetCurrentDir() + "screenshot\\" + time_str + ".png";
|
||||
asst.print_window(filename);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
2
meojson
BIN
readme/controlDelayRange.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
readme/gui.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
readme/printWindow.png
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
resource/CollectCredit.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
resource/CreditStore.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
resource/Friends.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
resource/FriendsList.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
resource/Loading.png
Normal file
|
After Width: | Height: | Size: 453 KiB |
BIN
resource/Mall.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 54 KiB |
BIN
resource/PopupCancel.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
resource/PopupConfirm.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 383 KiB After Width: | Height: | Size: 343 KiB |
BIN
resource/RationToday.png
Normal file
|
After Width: | Height: | Size: 811 KiB |
BIN
resource/Return.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 163 KiB |
BIN
resource/StartToVisit.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
resource/UsePrts.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
resource/VisitLimited.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
resource/VisitNext.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
resource/VisitNextBlack.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
@@ -1,15 +1,38 @@
|
||||
{
|
||||
"version": 0.2,
|
||||
"version": "0.4",
|
||||
"options": {
|
||||
"delay": {
|
||||
"type": "fixedTime",
|
||||
"fixedTime": 2000
|
||||
},
|
||||
"cache": true
|
||||
"identifyCache": true,
|
||||
"identifyCache_Doc": "图像识别缓存功能:开启后可以大幅降低CPU消耗,但需要保证要识别的按钮每次的位置不会改变。true-开启,false-关闭,默认true",
|
||||
"identifyDelay": 1000,
|
||||
"identifyDelay_Doc": "图像识别延时:越快操作越快,但会增加CPU消耗。单位毫秒,默认1000",
|
||||
"printWindow": true,
|
||||
"printWindow_Doc": "截图功能:开启后每次结算界面会截图到screenshot目录下。true-开启,false-关闭,默认true",
|
||||
"printWindowDelay": 3000,
|
||||
"printWindowDelay_Doc": "截图延时:每次到结算界面,掉落物品不是一次性出来的,有个动画,所以需要等一会再截图。单位毫秒,默认3000",
|
||||
"printWindowCropOffset": 5,
|
||||
"printWindowCropOffset_Doc": "截图额外裁剪:再额外把边框裁减掉一圈,不然企鹅物流有可能识别不出来。单位像素,默认5",
|
||||
"controlDelayRange": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"controlDelayRange_Doc": "点击随机延时:每次点击操作会进行随机延时,降低封号风险(好像也没听说过谁被封号的)。格式为 [ 最小延时, 最大延时 ],单位为毫秒。例如想设置3~5秒延时,即修改为[ 3000, 5000 ],默认0~0"
|
||||
},
|
||||
"handle_Doc": "下面的和模拟器窗口捕获逻辑有关,不需要修改",
|
||||
"handle": {
|
||||
"BlueStacks": {
|
||||
"Control": [
|
||||
"window": [
|
||||
{
|
||||
"class": "BS2CHINAUI",
|
||||
"window": "BlueStacks App Player"
|
||||
}
|
||||
],
|
||||
"view": [
|
||||
{
|
||||
"class": "BS2CHINAUI",
|
||||
"window": "BlueStacks App Player"
|
||||
}
|
||||
],
|
||||
"control": [
|
||||
{
|
||||
"class": "BS2CHINAUI",
|
||||
"window": "BlueStacks App Player"
|
||||
@@ -23,49 +46,49 @@
|
||||
"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
|
||||
"xOffset": 11,
|
||||
"yOffset": 46,
|
||||
"rightOffset": 11,
|
||||
"bottomOffset": 10
|
||||
},
|
||||
"Nox": {
|
||||
"Control": [
|
||||
"window": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "夜神模拟器"
|
||||
}
|
||||
],
|
||||
"View": [
|
||||
"view": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "夜神模拟器"
|
||||
}
|
||||
],
|
||||
"Window": [
|
||||
"control": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "夜神模拟器"
|
||||
}
|
||||
],
|
||||
"Width": 1298,
|
||||
"Height": 754,
|
||||
"xOffset": 0,
|
||||
"yOffset": -32
|
||||
"xOffset": 2,
|
||||
"yOffset": 39,
|
||||
"rightOffset": 39,
|
||||
"bottomOffset": 9
|
||||
},
|
||||
"LDPlayer": {
|
||||
"Control": [
|
||||
"window": [
|
||||
{
|
||||
"class": "LDPlayerMainFrame",
|
||||
"window": "雷电模拟器"
|
||||
}
|
||||
],
|
||||
"view": [
|
||||
{
|
||||
"class": "LDPlayerMainFrame",
|
||||
"window": "雷电模拟器"
|
||||
}
|
||||
],
|
||||
"control": [
|
||||
{
|
||||
"class": "LDPlayerMainFrame",
|
||||
"window": "雷电模拟器"
|
||||
@@ -75,25 +98,23 @@
|
||||
"window": "TheRender"
|
||||
}
|
||||
],
|
||||
"View": [
|
||||
{
|
||||
"class": "LDPlayerMainFrame",
|
||||
"window": "雷电模拟器"
|
||||
}
|
||||
],
|
||||
"Window": [
|
||||
{
|
||||
"class": "LDPlayerMainFrame",
|
||||
"window": "雷电模拟器"
|
||||
}
|
||||
],
|
||||
"Width": 1304,
|
||||
"Height": 756,
|
||||
"xOffset": 0,
|
||||
"yOffset": -35
|
||||
"yOffset": 35
|
||||
},
|
||||
"XYAZ": {
|
||||
"Control": [
|
||||
"window": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "逍遥模拟器"
|
||||
}
|
||||
],
|
||||
"view": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "逍遥模拟器"
|
||||
}
|
||||
],
|
||||
"control": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "逍遥模拟器"
|
||||
@@ -103,25 +124,25 @@
|
||||
"window": "MainWindowWindow"
|
||||
}
|
||||
],
|
||||
"View": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "逍遥模拟器"
|
||||
}
|
||||
],
|
||||
"Window": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "逍遥模拟器"
|
||||
}
|
||||
],
|
||||
"Width": 1282,
|
||||
"Height": 769,
|
||||
"xOffset": 0,
|
||||
"yOffset": -47
|
||||
"xOffset": 1,
|
||||
"yOffset": 48,
|
||||
"rightOffset": 1,
|
||||
"bottomOffset": 1
|
||||
},
|
||||
"Tencent": {
|
||||
"Control": [
|
||||
"window": [
|
||||
{
|
||||
"class": "TXGuiFoundation",
|
||||
"window": "腾讯手游助手"
|
||||
}
|
||||
],
|
||||
"view": [
|
||||
{
|
||||
"class": "TXGuiFoundation",
|
||||
"window": "腾讯手游助手"
|
||||
}
|
||||
],
|
||||
"control": [
|
||||
{
|
||||
"class": "TXGuiFoundation",
|
||||
"window": "腾讯手游助手"
|
||||
@@ -131,30 +152,78 @@
|
||||
"window": "AEngineRenderWindow"
|
||||
}
|
||||
],
|
||||
"View": [
|
||||
"xOffset": 1,
|
||||
"yOffset": 42
|
||||
},
|
||||
"MuMuAsst": {
|
||||
"window": [
|
||||
{
|
||||
"class": "TXGuiFoundation",
|
||||
"window": "腾讯手游助手"
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - 星云引擎"
|
||||
}
|
||||
],
|
||||
"Window": [
|
||||
"view": [
|
||||
{
|
||||
"class": "TXGuiFoundation",
|
||||
"window": "腾讯手游助手"
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - 星云引擎"
|
||||
}
|
||||
],
|
||||
"Width": 1282,
|
||||
"Height": 769,
|
||||
"control": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - 星云引擎"
|
||||
}
|
||||
],
|
||||
"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 } '",
|
||||
"displayRegex": "cur=%dx%d"
|
||||
},
|
||||
"xOffset": 0,
|
||||
"yOffset": -42
|
||||
"yOffset": 36
|
||||
},
|
||||
"MuMuEmulator": {
|
||||
"window": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - MuMu模拟器"
|
||||
}
|
||||
],
|
||||
"view": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - MuMu模拟器"
|
||||
}
|
||||
],
|
||||
"control": [
|
||||
{
|
||||
"class": "Qt5QWindowIcon",
|
||||
"window": "明日方舟 - MuMu模拟器"
|
||||
}
|
||||
],
|
||||
"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 } '",
|
||||
"displayRegex": "cur=%dx%d"
|
||||
},
|
||||
"xOffset": 0,
|
||||
"yOffset": 36,
|
||||
"rightOffset": 0,
|
||||
"bottomOffset": 0
|
||||
}
|
||||
},
|
||||
"tasks_Doc": "下面的和任务队列执行逻辑有关,不需要修改",
|
||||
"tasks": {
|
||||
"Begin": {
|
||||
"SanityBegin": {
|
||||
"filename": "",
|
||||
"threshold": 0,
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"UsePrts",
|
||||
"StartButton1",
|
||||
"StartButton2",
|
||||
"PRTS",
|
||||
@@ -164,9 +233,17 @@
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"UsePrts": {
|
||||
"filename": "UsePrts.png",
|
||||
"threshold": 0.8,
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"StartButton1"
|
||||
]
|
||||
},
|
||||
"StartButton1": {
|
||||
"filename": "StartButton1.png",
|
||||
"threshold": 0.99,
|
||||
"threshold": 0.8,
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"StartButton2",
|
||||
@@ -175,36 +252,57 @@
|
||||
]
|
||||
},
|
||||
"StartButton2": {
|
||||
"id": 2,
|
||||
"filename": "StartButton2.png",
|
||||
"threshold": 0.99,
|
||||
"type": "clickSelf",
|
||||
"rearDelay": 20000,
|
||||
"next": [
|
||||
"StartButton2",
|
||||
"PRTS"
|
||||
]
|
||||
},
|
||||
"PRTS": {
|
||||
"filename": "PRTS.png",
|
||||
"threshold": 0.98,
|
||||
"type": "doNothing",
|
||||
"rearDelay": 5000,
|
||||
"next": [
|
||||
"PRTS",
|
||||
"PrtsErrorConfirm",
|
||||
"EndOfAction"
|
||||
]
|
||||
},
|
||||
"EndOfAction": {
|
||||
"filename": "",
|
||||
"threshold": 0,
|
||||
"type": "printWindow",
|
||||
"next": [
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"Random": {
|
||||
"filename": "",
|
||||
"threshold": 0,
|
||||
"type": "clickRand",
|
||||
"type": "clickRect",
|
||||
"specificArea": [
|
||||
1100,
|
||||
700,
|
||||
150,
|
||||
30
|
||||
],
|
||||
"next": [
|
||||
"Loading",
|
||||
"StartButton1",
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"Loading": {
|
||||
"filename": "Loading.png",
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"StartButton1"
|
||||
]
|
||||
},
|
||||
"UseMedicine": {
|
||||
"filename": "UseMedicine.png",
|
||||
"threshold": 0.99,
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"MedicineConfirm"
|
||||
@@ -212,31 +310,34 @@
|
||||
},
|
||||
"MedicineConfirm": {
|
||||
"filename": "MedicineConfirm.png",
|
||||
"threshold": 0.98,
|
||||
"type": "clickSelf",
|
||||
"reduceOtherTimes": [
|
||||
"StartButton1"
|
||||
],
|
||||
"next": [
|
||||
"StartButton1"
|
||||
]
|
||||
},
|
||||
"UseStone": {
|
||||
"filename": "UseStone.png",
|
||||
"threshold": 0.99,
|
||||
"type": "stop",
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"StoneConfirm"
|
||||
]
|
||||
},
|
||||
"StoneConfirm": {
|
||||
"filename": "MedicineConfirm.png",
|
||||
"threshold": 0.98,
|
||||
"type": "clickSelf",
|
||||
"maxTimes": 0,
|
||||
"reduceOtherTimes": [
|
||||
"StartButton1"
|
||||
],
|
||||
"next": [
|
||||
"StartButton1"
|
||||
]
|
||||
},
|
||||
"PrtsErrorConfirm": {
|
||||
"filename": "PrtsErrorConfirm.png",
|
||||
"threshold": 0.98,
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"AbandonAction"
|
||||
@@ -244,11 +345,133 @@
|
||||
},
|
||||
"AbandonAction": {
|
||||
"filename": "AbandonAction.png",
|
||||
"threshold": 0.98,
|
||||
"type": "clickSelf",
|
||||
"reduceOtherTimes": [
|
||||
"StartButton1",
|
||||
"StartButton2",
|
||||
"Loading"
|
||||
],
|
||||
"next": [
|
||||
"Random"
|
||||
]
|
||||
},
|
||||
"VisitBegin": {
|
||||
"filename": "",
|
||||
"threshold": 0,
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"Friends",
|
||||
"FriendsList",
|
||||
"StartToVisit",
|
||||
"VisitNext",
|
||||
"VisitNextBlack",
|
||||
"ReturnToFriends"
|
||||
]
|
||||
},
|
||||
"ReturnToFriends": {
|
||||
"filename": "Return.png",
|
||||
"threshold": 0.85,
|
||||
"cacheThreshold": 0.85,
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"Friends",
|
||||
"ReturnToFriends"
|
||||
]
|
||||
},
|
||||
"Friends": {
|
||||
"filename": "Friends.png",
|
||||
"preDelay": 1000,
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"FriendsList"
|
||||
]
|
||||
},
|
||||
"FriendsList": {
|
||||
"filename": "FriendsList.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"StartToVisit"
|
||||
]
|
||||
},
|
||||
"StartToVisit": {
|
||||
"filename": "StartToVisit.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"VisitNext"
|
||||
]
|
||||
},
|
||||
"VisitNext": {
|
||||
"filename": "VisitNext.png",
|
||||
"type": "clickSelf",
|
||||
"maxTimes": 21,
|
||||
"exceededNext": [
|
||||
"ReturnToMall"
|
||||
],
|
||||
"next": [
|
||||
"VisitNext",
|
||||
"VisitNextBlack"
|
||||
]
|
||||
},
|
||||
"ReturnToMall": {
|
||||
"filename": "Return.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"Mall",
|
||||
"ReturnToMall",
|
||||
"ReturnToMallConfirm"
|
||||
]
|
||||
},
|
||||
"ReturnToMallConfirm": {
|
||||
"filename": "PopupConfirm.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"ReturnToMall"
|
||||
]
|
||||
},
|
||||
"Mall": {
|
||||
"filename": "Mall.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"CreditStore"
|
||||
]
|
||||
},
|
||||
"CreditStore": {
|
||||
"filename": "CreditStore.png",
|
||||
"threshold": 0.85,
|
||||
"rearDelay": 1000,
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"CollectCredit",
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"CollectCredit": {
|
||||
"filename": "CollectCredit.png",
|
||||
"type": "clickSelf",
|
||||
"next": [
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"VisitLimited": {
|
||||
"filename": "VisitLimited.png",
|
||||
"threshold": 1,
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"ReturnToMall"
|
||||
]
|
||||
},
|
||||
"VisitNextBlack": {
|
||||
"filename": "VisitNextBlack.png",
|
||||
"type": "doNothing",
|
||||
"next": [
|
||||
"ReturnToMall"
|
||||
]
|
||||
},
|
||||
"Stop": {
|
||||
"filename": "",
|
||||
"threshold": 0,
|
||||
"type": "stop",
|
||||
"next": []
|
||||
}
|
||||
}
|
||||
}
|
||||
2
update_resource.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
xcopy /e /y /i resource x64\Debug\resource
|
||||
xcopy /e /y /i resource x64\Release\resource
|
||||