mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
Merge branch 'MaaAssistantArknights:dev' into dev
This commit is contained in:
149
README-en.md
Normal file
149
README-en.md
Normal file
@@ -0,0 +1,149 @@
|
||||
<div align="center">
|
||||
|
||||
<img alt="LOGO" src="https://user-images.githubusercontent.com/18511905/148931479-23aef436-2fc1-4c1e-84c9-bae17be710a5.png" width=360 height=270/>
|
||||
|
||||
# MaaAssistantArknights
|
||||
|
||||
<br>
|
||||
<div>
|
||||
<img alt="C++" src="https://img.shields.io/badge/c++-17-%2300599C?logo=cplusplus">
|
||||
</div>
|
||||
<div>
|
||||
<img alt="platform" src="https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-blueviolet">
|
||||
</div>
|
||||
<div>
|
||||
<img alt="license" src="https://img.shields.io/github/license/MaaAssistantArknights/MaaAssistantArknights">
|
||||
<img alt="commit" src="https://img.shields.io/github/commit-activity/m/MaaAssistantArknights/MaaAssistantArknights?color=%23ff69b4">
|
||||
<img alt="stars" src="https://img.shields.io/github/stars/MaaAssistantArknights/MaaAssistantArknights?style=social">
|
||||
</div>
|
||||
<br>
|
||||
|
||||
[中文版本README](README.md)
|
||||
|
||||
MAA stands for MAA Assistant Arknights
|
||||
|
||||
An Arknights assistant
|
||||
|
||||
Based on image recognition, helps you to complete daily quests efficiently!
|
||||
|
||||
Development in progress ✿✿ヽ(°▽°)ノ✿
|
||||
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- Auto-battle, drop items recognition, auto-uploading to [Penguin Stats](https://penguin-stats.cn/)
|
||||
- Auto-shifting in the infrastructure, auto efficiency calculation of operators, optimal solution in single facility
|
||||
- Auto-recruitment, support for expedited plan
|
||||
- Visiting friends, collecting credits and purchasing items, collecting daily rewards, completing daily quests in one click!
|
||||
- Auto-battle for Integrated Strategy (I.S.) for collecting originium ingots and candles.
|
||||
- **New feature! Importing JSON task file for auto-battle!** [Video](https://www.bilibili.com/video/BV14u411673q/)
|
||||
|
||||
Talk is cheap. Show me the pictures!
|
||||
|
||||

|
||||

|
||||
|
||||
## Download
|
||||
|
||||
[Stable](https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases/latest)
|
||||
[Development](https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases)
|
||||
|
||||
## How to Use
|
||||
|
||||
### Basic Settings
|
||||
|
||||
1. Follow the [Simulator Support](docs/en/SIMULATOR_SUPPORT.md) to configure your simulator.
|
||||
2. Unzip the archive file to an **ASCII-only** directory
|
||||
3. All settings are not changeable after running except `Auto shutdown`.
|
||||
|
||||
The program supports `16:9` resolution the best, with resolution larger than or equal to `1280 * 720`. Non-`16:9` resolution may cause some unknown issues and will be supported in future.
|
||||
|
||||
See also: [User Manual](docs/en/USER_MANUAL.md)
|
||||
|
||||
## FAQ
|
||||
|
||||
- The program crashes immediately when I try to run it.
|
||||
- Connection error/not knowing how to fill in ADB path.
|
||||
- Wrong recognition/program freezes after starting
|
||||
- Custom connection settings
|
||||
|
||||
Please refer to: [FAQ](docs/en/FAQ.md)
|
||||
|
||||
## Associated Projects
|
||||
|
||||
- New GUI: [MaaAsstElectronUI](https://github.com/MaaAssistantArknights/MaaAsstElectronUI) (Development in progress, welcome to join us!)
|
||||
- Update server: [MaaDownloadServer](https://github.com/MaaAssistantArknights/MaaDownloadServer) (Development in progress, welcome to join us!)
|
||||
- Co-pilot (auto-battle) server: [MaaCopilotServer](https://github.com/MaaAssistantArknights/MaaCopilotServer) (Development in progress, welcome to join us!)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
### Open-source Libraries
|
||||
|
||||
- Image recognition: [opencv](https://github.com/opencv/opencv.git)
|
||||
- ~~OCR: [chineseocr_lite](https://github.com/DayBreak-u/chineseocr_lite.git)~~
|
||||
- OCR: [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR)
|
||||
- ~~Item drop recognition: [Penguin Stats recognizer](https://github.com/penguin-statistics/recognizer)~~
|
||||
- Map tile recognition: [Arknights-Tile-Pos](https://github.com/yuanyan3060/Arknights-Tile-Pos)
|
||||
- C++ JSON library: [meojson](https://github.com/MistEO/meojson.git)
|
||||
- C++ operator parser: [calculator](https://github.com/kimwalisch/calculator)
|
||||
- C++ Base64 encoding/decoding[cpp-base64](https://github.com/ReneNyffenegger/cpp-base64)
|
||||
- C++ ZIP library: [zlib](https://github.com/madler/zlib)
|
||||
- C++ Gzip library: [gzip-hpp](https://github.com/mapbox/gzip-hpp)
|
||||
- WPF MVVW framework: [Stylet](https://github.com/canton7/Stylet)
|
||||
- WPF control library: [HandyControl](https://github.com/HandyOrg/HandyControl)
|
||||
- C# JSON library: [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
|
||||
- Downloader: [aria2](https://github.com/aria2/aria2)
|
||||
|
||||
### Data Source
|
||||
|
||||
- ~~Recruitment data:[ArkTools](https://www.bigfun.cn/tools/aktools/hr)~~
|
||||
- Operators and infrastructure data:[PRTS Arknights Wiki (Chinese)](http://prts.wiki/)
|
||||
- Stage data: [Penguin Stats](https://penguin-stats.cn/)
|
||||
- Gamedata and resources: [Arknights Bot Resource](https://github.com/yuanyan3060/Arknights-Bot-Resource)
|
||||
|
||||
### Contributors
|
||||
|
||||
Thanks to all friends who contribute to development/testing for making MAA better! (*´▽`)ノノ
|
||||
|
||||
[](https://github.com/MaaAssistantArknights/MaaAssistantArknights/graphs/contributors)
|
||||
|
||||
## Development Related Information
|
||||
|
||||
### Windows
|
||||
|
||||
Open `MeoAssistantArknights.sln` with Visual Studio 2019 ~~or higher version~~. All settings have been configured properly.
|
||||
|
||||
### Linux/MacOS
|
||||
|
||||
Please refer to [Linux Tutorial](docs/en/LINUX_TUTORIAL.md)
|
||||
|
||||
### API
|
||||
|
||||
- [C interface](include/AsstCaller.h): [Integration Example](tools/TestCaller/main.cpp)
|
||||
- [Python interface](src/Python/asst.py): [Integration Example](src/Python/sample.py)
|
||||
- [Golang interface](src/Golang/maa/): [Integration Example](src/Golang/cli.go) (deprecated)
|
||||
- [Dart interface](src/dart/)
|
||||
- [Java interface](src/Java/Maaj):[Integration Example](src/Java/Maaj/src/main/java/com/iguigui/maaj/MaaJavaSample.java)
|
||||
- [Integration Documentation](docs/en/INTEGRATION.md)
|
||||
- [Callback Schema](docs/en/CALLBACK_SCHEMA.md)
|
||||
- [Task Schema](docs/en/TASK_SCHEMA.md)
|
||||
- [Copilot Schema](docs/en/COPILOT_SCHEMA.md)
|
||||
|
||||
### For Novice Users of Git
|
||||
|
||||
[Contributing](docs/en/CONTRIBUTING.md)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
- The logo of this software is NOT granted rights under AGPL 3.0 License. The artist [耗毛](https://weibo.com/u/3251357314) and all developers of the software reserves all rights. The logo of the software shall not be used without authorization even if the project has an AGPL 3.0 License. Nor shall the logo be used for commercial purposes without authorization.
|
||||
- The software is an open-source, free of charge software only for studying and communication purposes. There is no agreement or understanding between the developers of the software and the 3rd party person who uses this software as an assistant and charges you. In that case, the developers of the software is not responsible for the problems and consequences caused.
|
||||
|
||||
## Advertisement
|
||||
|
||||
[Bilibili Live](https://live.bilibili.com/2808861): live coding on this program
|
||||
[Technical Discussion & Talk](https://jq.qq.com/?_wv=1027&k=ypbzXcA2):QQ Group
|
||||
[Copilot JSON Sharing](https://jq.qq.com/?_wv=1027&k=1giyMpPb)
|
||||
[Dev Group](https://jq.qq.com/?_wv=1027&k=JM9oCk3C)
|
||||
|
||||
Please click "Star" if you consider it helpful! Thank you for your support!
|
||||
@@ -18,6 +18,8 @@
|
||||
</div>
|
||||
<br>
|
||||
|
||||
[README in English](README-en.md)
|
||||
|
||||
MAA 的意思是 MAA Assistant Arknights
|
||||
|
||||
一款明日方舟游戏小助手
|
||||
|
||||
425
docs/en/CALLBACK_SCHEMA.md
Normal file
425
docs/en/CALLBACK_SCHEMA.md
Normal file
@@ -0,0 +1,425 @@
|
||||
## Callback Schema
|
||||
|
||||
### Prototype
|
||||
|
||||
```c++
|
||||
typedef void(ASST_CALL* AsstCallback)(int msg, const char* details, void* custom_arg);
|
||||
```
|
||||
|
||||
### Overview
|
||||
|
||||
- `int msg`
|
||||
The message type
|
||||
|
||||
```c++
|
||||
enum class AsstMsg
|
||||
{
|
||||
/* Global Info */
|
||||
InternalError = 0, // Internal error
|
||||
InitFailed, // Initialization failure
|
||||
ConnectionInfo, // Connection info
|
||||
AllTasksCompleted, // Whether all tasks have been completed
|
||||
/* TaskChain Info */
|
||||
TaskChainError = 10000, // Errors in task chain execution/recognition
|
||||
TaskChainStart, // Task chain starts
|
||||
TaskChainCompleted, // Task chain completes
|
||||
TaskChainExtraInfo, // Extra information about task chain
|
||||
/* SubTask Info */
|
||||
SubTaskError = 20000, // Errors in subtask execution/recognition
|
||||
SubTaskStart, // Subtask starts
|
||||
SubTaskCompleted, // Subtask completes
|
||||
SubTaskExtraInfo // Extra information about subtask
|
||||
};
|
||||
```
|
||||
|
||||
- `const char* details`
|
||||
Message details, JSON. See also: [Field Description](#field-description)
|
||||
- `void* custom_arg`
|
||||
Custom arguments of the caller, will pass the `custom_arg` argument of `AsstCreateEx` interface. C-like languages can pass the `this` pointer with it.
|
||||
|
||||
### Field Description
|
||||
|
||||
#### InternalError
|
||||
|
||||
Todo
|
||||
|
||||
#### InitFailed
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"what": string, // Error type
|
||||
"why": string, // Error reason
|
||||
"details": object // Error details
|
||||
}
|
||||
```
|
||||
|
||||
### ConnectionInfo
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"what": string, // Info type
|
||||
"why": string, // Info reason
|
||||
"uuid": string, // UUID (empty when connection fails)
|
||||
"details": {
|
||||
"adb": string, // adb_path argument of AsstConnect interface
|
||||
"address": string, // address argument of AsstConnect interface
|
||||
"config": string // config argument of AsstConnect interface
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
#### Commonly-used `What` Field Values
|
||||
|
||||
- `ConnectFailed`
|
||||
Connection failed.
|
||||
- `Connected`
|
||||
Connected. Note that the `uuid` field is empty now (and will be retrieved in the next step)
|
||||
- `UuidGetted`
|
||||
UUID has been retrieved.
|
||||
- `UnsupportedResolution`
|
||||
The resolution is not supported.
|
||||
|
||||
#### AllTasksCompleted
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"taskchain": string, // Last task chain
|
||||
"uuid": string // UUID
|
||||
}
|
||||
```
|
||||
|
||||
##### Commonly-used `taskchain` Field Values
|
||||
|
||||
- `StartUp`
|
||||
Start-up.
|
||||
- `Fight`
|
||||
Fighting.
|
||||
- `Mall`
|
||||
Mall.
|
||||
- `Recruit`
|
||||
Auto-recruitment.
|
||||
- `RecruitCalc`
|
||||
Recruitment calculation.
|
||||
- `Infrast`
|
||||
Infrastructure.
|
||||
- `Roguelike`
|
||||
Roguelike.
|
||||
- `Debug`
|
||||
Debug.
|
||||
|
||||
#### Information Related to TaskChain
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"taskchain": string, // Current task chain
|
||||
"taskid": int, // Current task ID
|
||||
"uuid": string // UUID
|
||||
}
|
||||
```
|
||||
|
||||
#### TaskChainExtraInfo
|
||||
|
||||
Todo
|
||||
|
||||
#### Information Related to SubTask
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"subtask": string, // Subtask name
|
||||
"class": string, // Subtask class
|
||||
"taskchain": string, // Current task chain
|
||||
"taskid": int, // Current task ID
|
||||
"details": object, // Details
|
||||
"uuid": string // UUID
|
||||
}
|
||||
```
|
||||
|
||||
##### Commonly-used `subtask` Field Values
|
||||
|
||||
- `ProcessTask`
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"task": "StartButton2", // Task name
|
||||
"action": 512,
|
||||
"exec_times": 1, // Execution times
|
||||
"max_times": 999, // Maximum execution times
|
||||
"algorithm": 0
|
||||
}
|
||||
```
|
||||
|
||||
- Todo Other
|
||||
|
||||
###### Commonly-used `task` Field Values
|
||||
|
||||
- `StartButton2`
|
||||
Starting.
|
||||
- `MedicineConfirm`
|
||||
Confirmation of using Sanity Potion.
|
||||
- `StoneConfirm`
|
||||
Confirmation of using Originite Prime.
|
||||
- `RecruitRefreshConfirm`
|
||||
Confirmation of refreshing recruitment list.
|
||||
- `RecruitConfirm`
|
||||
Confirmation of recruitment.
|
||||
- `RecruitNowConfirm`
|
||||
Confirmation of expedited recruitment.
|
||||
- `ReportToPenguinStats`
|
||||
Reporting to Penguin Stats.
|
||||
- `InfrastDormDoubleConfirmButton`
|
||||
Double confirmation at infrastructure, only happens when there is a conflict with other operators.
|
||||
- `Roguelike1Start`
|
||||
Integrated Strategy: starting.
|
||||
- `Roguelike1StageTraderInvestConfirm`
|
||||
Integrated Strategy: trading items with Originium Ingot.
|
||||
- `Roguelike1StageTraderInvestSystemFull`
|
||||
Integrated Strategy: trading system full.
|
||||
- `Roguelike1ExitThenAbandon`
|
||||
Integrated Strategy: exit confirmation.
|
||||
- `Roguelike1MissionCompletedFlag`
|
||||
Integrated Strategy: mission completed.
|
||||
- `Roguelike1MissionFailedFlag`
|
||||
Integrated Strategy: mission failed.
|
||||
- `Roguelike1StageSafeHouseEnter`
|
||||
Integrated Strategy: Cunning Merchant
|
||||
- `Roguelike1StageSafeHouseEnter`
|
||||
Integrated Strategy: Safehouse
|
||||
- `Roguelike1StageEncounterEnter`
|
||||
Integrated Strategy: Chance Meeting
|
||||
- `Roguelike1StageCambatDpsEnter`
|
||||
Integrated Strategy: Operation
|
||||
- `Roguelike1StageEmergencyDps`
|
||||
Integrated Strategy: Emergency Operation
|
||||
- `Roguelike1StageDreadfulFoe`
|
||||
Integrated Strategy: Dreadful Foe
|
||||
- Todo Other
|
||||
|
||||
#### SubTaskExtraInfo
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"taskchain": string, // Current task chain
|
||||
"class": string, // Subtask class
|
||||
"what": string, // Information type
|
||||
"details": object, // Information details
|
||||
"uuid": string, // UUID
|
||||
}
|
||||
```
|
||||
|
||||
##### Commonly-used `what` And `details` Field Values
|
||||
|
||||
- `StageDrops`
|
||||
Stage drop information
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"drops": [ // dropped items
|
||||
{
|
||||
"itemId": "3301",
|
||||
"quantity": 2,
|
||||
"itemName": "技巧概要·卷1" // Skill Summary - 1
|
||||
},
|
||||
{
|
||||
"itemId": "3302",
|
||||
"quantity": 1,
|
||||
"itemName": "技巧概要·卷2" // Skill Summary - 2
|
||||
},
|
||||
{
|
||||
"itemId": "3303",
|
||||
"quantity": 2,
|
||||
"itemName": "技巧概要·卷3" // Skill Summary - 3
|
||||
}
|
||||
],
|
||||
"stage": { // 关卡信息
|
||||
"stageCode": "CA-5",
|
||||
"stageId": "wk_fly_5"
|
||||
},
|
||||
"stars": 3, // Stage clear ★
|
||||
"stats": [ // Statistics of drops
|
||||
{
|
||||
"itemId": "3301",
|
||||
"itemName": "技巧概要·卷1", // Skill Summary - 1
|
||||
"quantity": 4
|
||||
},
|
||||
{
|
||||
"itemId": "3302",
|
||||
"itemName": "技巧概要·卷2", // Skill Summary - 2
|
||||
"quantity": 3
|
||||
},
|
||||
{
|
||||
"itemId": "3303",
|
||||
"itemName": "技巧概要·卷3", // Skill Summary - 3
|
||||
"quantity": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `RecruitTagsDetected`
|
||||
Recruitment tags detected
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"tags": [
|
||||
"费用回复", // DP-Recovery
|
||||
"防护", // Defense
|
||||
"先锋干员", // Vanguard
|
||||
"辅助干员", // Support
|
||||
"近战位" // Melee
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `RecruitSpecialTag`
|
||||
Special recruitment tags detected
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"tag": "高级资深干员" // Senior operator
|
||||
}
|
||||
```
|
||||
|
||||
- `RecruitResult`
|
||||
Recruitment result
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"level": 4, // ★ in total
|
||||
"result": [
|
||||
{
|
||||
"tags": [
|
||||
"削弱" // Debuff
|
||||
],
|
||||
"level": 4, // Rarity of these tags
|
||||
"opers": [
|
||||
{
|
||||
"name": "初雪", // Pramanix
|
||||
"level": 5 // ★ of the operator
|
||||
},
|
||||
{
|
||||
"name": "陨星", // Meteorite
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"name": "槐琥", // Waai Fu
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"name": "夜烟", // Haze
|
||||
"level": 4
|
||||
},
|
||||
{
|
||||
"name": "流星", // Meteor
|
||||
"level": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tags": [
|
||||
"减速", // Slow
|
||||
"术师干员" // Caster
|
||||
],
|
||||
"level": 4,
|
||||
"opers": [
|
||||
{
|
||||
"name": "夜魔", // Nightmare
|
||||
"level": 5
|
||||
},
|
||||
{
|
||||
"name": "格雷伊", // Greyy
|
||||
"level": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tags": [
|
||||
"削弱", // Debuff
|
||||
"术师干员" // Caster
|
||||
],
|
||||
"level": 4,
|
||||
"opers": [
|
||||
{
|
||||
"name": "夜烟", // Haze
|
||||
"level": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `RecruitTagsSelected`
|
||||
Recruitment tags selected
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"tags": [
|
||||
"减速", // Slow
|
||||
"术师干员" // Caster
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `EnterFacility`
|
||||
Entering the facility
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"facility": "Mfg", // Facility name
|
||||
"index": 0 // Facility ID
|
||||
}
|
||||
```
|
||||
|
||||
- `NotEnoughStaff`
|
||||
Available operators not enough
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"facility": "Mfg", // Facility name
|
||||
"index": 0 // Facility ID
|
||||
}
|
||||
```
|
||||
|
||||
- `ProductOfFacility`
|
||||
Production of the facility
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"product": "Money", // Product
|
||||
"facility": "Mfg", // Facility name
|
||||
"index": 0 // Facility ID
|
||||
}
|
||||
```
|
||||
|
||||
- `StageInfo`
|
||||
Auto-battle stage info
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"name": string // Stage name
|
||||
}
|
||||
```
|
||||
|
||||
- `StageInfoError`
|
||||
Auto-battle stage info error
|
||||
|
||||
- `PenguinId`
|
||||
Penguin ID
|
||||
|
||||
```jsonc
|
||||
// Example of corresponding details field
|
||||
{
|
||||
"id": string
|
||||
}
|
||||
```
|
||||
130
docs/en/COPILOT_SCHEMA.md
Normal file
130
docs/en/COPILOT_SCHEMA.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Copilot Schema
|
||||
|
||||
Usage of `resource/copilot/*.json` and field description.
|
||||
|
||||
## Overview
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"stage_name": "暴君", // Stage name, required. Name should be in Chinese except for C.C. (contingency contracts)
|
||||
"opers": [ // Operator list
|
||||
{
|
||||
"name": "棘刺", // Operator name
|
||||
|
||||
"skill": 3, // Skill ID with range [1, 3], optional, 1 by default
|
||||
|
||||
"skill_usage": 0, // Skill usage, optional, 0 by default
|
||||
// 0 - Used on `actions`
|
||||
// 1 - Used when ready (e.g. Thorns: Destreza, Myrtle: Support Beta)
|
||||
// 2 - Used when ready, only once(e.g. Mountain: Sweeping Stance)
|
||||
// 3 - Auto-decision (not implemented)
|
||||
// 0 for auto skills
|
||||
|
||||
"requirements": { // Requirements, optional, empty by default
|
||||
"elite": 2, // Elite requirement, optional, 0 by default
|
||||
"level": 90, // Level requirement, optional, 0 by default
|
||||
"skill_level": 10, // Skill level requirement, optional, 0 by default
|
||||
"module": 1, // Module requirement, optional, 0 by default
|
||||
"potentiality": 1 // Potential requirement, optional, 0 by default
|
||||
}
|
||||
},
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"name": "任意正常群奶", // Group name, required
|
||||
// Any name is accepted as long as it matches the `name` field in `deploy` below
|
||||
|
||||
"opers": [ // Operators to be chosen randomly, similar to the `opers` field above. Operators with higher levels have higher priority.
|
||||
{
|
||||
"name": "夜莺", // Nightingale
|
||||
"skill": 3,
|
||||
"skill_usage": 2 // Skill CD may differ
|
||||
},
|
||||
{
|
||||
"name": "白面鸮", // Ptilopsis
|
||||
"skill": 2,
|
||||
"skill_usage": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"actions": [ // Actions in order, required. Will be executed sequentially
|
||||
{
|
||||
"type": "部署", // Action type, optional, "Deploy" by default
|
||||
// "Deploy" | "Skill" | "Retreat" | "SpeedUp" | "BulletTime" | "SkillUsage"
|
||||
// "部署" | "技能" | "撤退" | "二倍速" | "子弹时间" | "技能用法"
|
||||
// Both English and Chinese are supported
|
||||
// "Deploy" will wait until the cost is enough (unless timeout)
|
||||
// "Skill" will wait until the skill is ready (unless timeout)
|
||||
// "SpeedUp" is switchable, i.e. after using it will become 2x speed, and using it again will make it back to normal speed
|
||||
// "BulletTime" is the 1/5 speed after clicking any operator. Proceeding with any other action will make it back to normal speed
|
||||
|
||||
"kills": 0, // Waiting until the number of kills required is reached, optional, 0 by default
|
||||
|
||||
"cost_changes": 5, // Waiting until the cost changes for the amount specified, optional, 0 by default
|
||||
// Note that it calculates since the action starts (based on the cost of the previous action)
|
||||
// Recognition is accurate when the cost is 2 digits. Not recommended for 3-digit costs.
|
||||
// TODO: Other conditions
|
||||
// TODO: "condition_type": 0, // Condition aggregation type, optional, 0 by default
|
||||
// // 0 - AND; 1 - OR
|
||||
|
||||
"name": "棘刺", // Operator/group name, required when `type` is one of "Deploy" | "Skill" | "Retreat"
|
||||
|
||||
"location": [ 5, 5 ], // Position for deployment
|
||||
// Required when `type` is "Deploy"
|
||||
// Optional when `type` is "Retreat"
|
||||
// Recommended only when multiple summons exist, retreating with location instead of name
|
||||
// Please simply use name to retreat for normal operators
|
||||
|
||||
"direction": "左", // Direction for deployment, required when `type` is "Deploy"
|
||||
// "Left" | "Right" | "Up" | "Down" | "None"
|
||||
// "左" | "右" | "上" | "下" | "无"
|
||||
// Both English and Chinese are supported
|
||||
|
||||
"skill_usage": 1, // Override skill usage settings, required when `type` is "SkillUsage"
|
||||
// E.g.: Myrtle needs to attack without using the skill at the beginning, and use the skill automatically later.
|
||||
// Set it to 1 in that case.
|
||||
|
||||
"pre_delay": 0, // Pre-delay in ms, optional, 0 by default
|
||||
"rear_delay": 0, // Post-delay in ms, optional, 0 by default
|
||||
|
||||
// "timeout": 999999999, // Reserved field, not implemented
|
||||
// Timeout time in ms, optional when `type` is "Deploy" | "Skill", INT_MAX by default
|
||||
// Will proceed with the next action when timeout
|
||||
|
||||
"doc": "下棘刺了!", // Description, optional, displayed on the UI with no effects
|
||||
"doc_color": "orange" // Description colour, optional, displayed on the UI with no effects
|
||||
},
|
||||
// Example 1
|
||||
{
|
||||
"name": "任意正常群奶",
|
||||
"location": [ 5, 6 ],
|
||||
"direction": "右"
|
||||
},
|
||||
// Example 2
|
||||
{
|
||||
"name": "史尔特尔",
|
||||
"location": [ 4, 5 ],
|
||||
"direction": "左",
|
||||
"doc": "你史尔特尔奶奶来啦!",
|
||||
"doc_color": "red"
|
||||
},
|
||||
// Example 3
|
||||
{
|
||||
"type": "二倍速"
|
||||
}
|
||||
],
|
||||
"minimum_required": "v4.0", // Minimum required MAA version, required, reserved field, not implemented
|
||||
"doc": { // Description, optional
|
||||
"title": "低练度高成功率作业",
|
||||
"title_color": "dark",
|
||||
"details": "对练度要求很低balabala……", // You can write your name here, video link, walkthrough link, etc.
|
||||
"details_color": "dark"
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
[Sample](../resource/copilot/test.json)
|
||||
[GA-EX8 Raid](../resource/copilot/GA-EX8-raid.json)
|
||||
@@ -1,6 +1,6 @@
|
||||
## Frequently Asked Questions
|
||||
|
||||
### The program crashes immediately when I try to run it.
|
||||
### The program crashes immediately when I try to run it
|
||||
|
||||
- Possible solution 1: you are missing some runtime libraries.
|
||||
Please try installing [Visual C++ Redistributable](https://docs.microsoft.com/en/cpp/windows/latest-supported-vc-redist?view=msvc-160#visual-studio-2015-2017-2019-and-2022), [.NET Framework 4.8](https://dotnet.microsoft.com/download/dotnet-framework/net48) and restart the program.
|
||||
@@ -15,7 +15,7 @@
|
||||
Tips: please refer to the [Usage](../README-en.md#Usage) section to ensure that you are using your simulator correctly.
|
||||
|
||||
- Approach 1: find the installation path of your simulator, where there may be a file named `adb.exe` (or something similar, e.g. `nox_adb.exe`, `HD-adb.exe`, `adb_server.exe`, etc., EXE files with `adb`). Simply choose the file in the connection settings of MAA!
|
||||
- Approach 2: please refer to the [Custom Connection](#Custom Connection) section.
|
||||
- Approach 2: please refer to the [Custom Connection](#custom-connection) section.
|
||||
- Approach 3: change another simulator, such as [Bluestacks international version](https://www.bluestacks.com/download.html) Nougat 64 bit
|
||||
- Approach 4: change the code related. You can find the code [here](../src/MeoAsstGui/Helper/WinAdapter.cs) written in C# which is related to the hook on the simulator process and getting ADB path. Feel free to submit PR to us!
|
||||
|
||||
|
||||
65
docs/en/INTEGRATED_STRATEGY_SCHEMA.md
Normal file
65
docs/en/INTEGRATED_STRATEGY_SCHEMA.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# Integrated Strategy (I.S.) Schema
|
||||
|
||||
Usage of `resource/roguelike/*.json` and description of each field
|
||||
|
||||
## Overview
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"stage_name": "驯兽小屋", // Stage name, required
|
||||
"actions": [ // Actions in order, required. Will be executed sequentially
|
||||
{
|
||||
"type": "部署", // Action type, optional, "Deploy" by default
|
||||
// "Deploy" | "Skill" | "Retreat" | "AllSkill"
|
||||
// "部署" | "技能" | "撤退" | "全部技能"
|
||||
// Both English and Chinese are supported
|
||||
// "Deploy" will wait until the cost is enough (unless timeout)
|
||||
// "Skill" will wait until the skill is ready (unless timeout)
|
||||
// Use it based on skill effects and CDs of operators (e.g. Mountain: Sweeping Stance, switchable skill)
|
||||
// "AllSkill" will use all skills of operators with `skill_usage == 3`
|
||||
|
||||
"kills": 0, // Waiting until the number of kills required is reached, optional, 0 by default
|
||||
// TODO: Other conditions
|
||||
// TODO: "condition_type": 0, // Condition aggregation type, optional, 0 by default
|
||||
// // 0 - AND; 1 - OR
|
||||
|
||||
"roles": [ // Classes of the operators, optional, empty by default, meaning all classes are acceptable
|
||||
// The list is ordered, with the first item having the highest priority
|
||||
// Meele/ranged operators are chosen automatically. Non-deployable operators will be ignored.
|
||||
// The list will be skipped if none of the classes are available.
|
||||
"近卫", // Guard
|
||||
"先锋", // Vanguard
|
||||
"重装", // Defender
|
||||
"召唤物" // Summon
|
||||
],
|
||||
|
||||
"waiting_cost": false, // Whether to wait for the cost to be enough for class with higher priority in `roles` list, optional, `false` by default
|
||||
// `true` means to use existing class in the `roles` list that has the highest priority, waiting for the cost to be enough.
|
||||
// `false` means to use existing class in the `roles` list that has the highest priority and enough cost.
|
||||
|
||||
"location": [ 5, 5 ], // Location of the operator, required
|
||||
|
||||
"direction": "左", // Direction for deployment, required when `type` is "Deploy"
|
||||
// "Left" | "Right" | "Up" | "Down" | "None"
|
||||
// "左" | "右" | "上" | "下" | "无"
|
||||
// Both English and Chinese are supported
|
||||
|
||||
"pre_delay": 0, // Pre-delay in ms, optional, 0 by default
|
||||
"rear_delay": 0, // Post-delay in ms, optional, 0 by default
|
||||
|
||||
"timeout": 999999999 // Timeout time in ms, optional when `type` is "Deploy", INT_MAX by default
|
||||
// Will proceed with the next action when timeout
|
||||
},
|
||||
{ // Example
|
||||
"location": [6, 6],
|
||||
"roles": [
|
||||
"近卫", // Guard
|
||||
"先锋", // Vanguard
|
||||
"重装", // Defender
|
||||
"召唤物" // Summon
|
||||
],
|
||||
"direction": "左"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
171
docs/en/INTEGRATION.md
Normal file
171
docs/en/INTEGRATION.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Integration
|
||||
|
||||
## API
|
||||
|
||||
### `AsstAppendTask`
|
||||
|
||||
#### Prototype
|
||||
|
||||
```c++
|
||||
TaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const char* params);
|
||||
```
|
||||
|
||||
#### Description
|
||||
|
||||
Appends a task.
|
||||
|
||||
#### Return Value
|
||||
|
||||
- `TaskId`
|
||||
The task ID if the task is successfully appended, for the following configuration;
|
||||
0 if the task is not successfully appended.
|
||||
|
||||
#### Parameter Description
|
||||
|
||||
- `AsstHandle handle`
|
||||
Instance handle
|
||||
- `const char* type`
|
||||
Task type
|
||||
- `const char* params`
|
||||
Task parameters in JSON
|
||||
|
||||
##### List of Task Types
|
||||
|
||||
- `StartUp`
|
||||
Start-up
|
||||
No parameters required
|
||||
|
||||
- `Fight`
|
||||
Operation
|
||||
|
||||
```jsonc
|
||||
// Corresponding task parameters
|
||||
{
|
||||
"stage": string, // Stage name, optional, by default "当前关卡". Editing in run-time is not supported.
|
||||
"medicine": int, // Maximum number Sanity Potion used, optional, by default 0
|
||||
"stone": int, // Maximum number of Originite Prime used, optional, by default 0
|
||||
"times": int, // Maximum times, optional, by default infinite
|
||||
"report_to_penguin": bool, // Whether to upload data to Pengiun Stats, optional, by default false
|
||||
"penguin_id": string, // Penguin Stats ID, optional, by default empty. Available only when `report_to_penguin` is `true`.
|
||||
"server": string // Server, optional, by default "CN", will affect the drop recognition and upload
|
||||
// Options:"CN" | "US" | "JP" | "KR"
|
||||
}
|
||||
```
|
||||
|
||||
- `Recruit`
|
||||
Recruitment
|
||||
|
||||
```jsonc
|
||||
// Corresponding task parameters
|
||||
{
|
||||
"refresh": bool, // Whether to refresh 3★ tags, optional, by default false
|
||||
"select": [ // Tag level to click, required
|
||||
int,
|
||||
...
|
||||
],
|
||||
"confirm": [ // Tag level for confirmation, required. Can be set to empty array for calculation only.
|
||||
int,
|
||||
...
|
||||
],
|
||||
"times": int, // The times of recruitment, optional, by default 0. Can be set to 0 for calculation only.
|
||||
"set_time": bool, // Whether to set time to 9 hours, available only when `times` is 0, optional, by default true
|
||||
"expedite": bool, // Whether to use expedited plans, optional, by default false
|
||||
"expedite_times": int, // The times of using expedited plans, available only when `expedite` is `true`
|
||||
// Optional, by default infinity until `times` reaches its limitation.
|
||||
}
|
||||
```
|
||||
|
||||
- `Infrast`
|
||||
Infrastructure shifting
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"mode": int, // Shift mode, reserved, optional. Editing in run-time is not supported.
|
||||
"facility": [ // Facilities for shifting, required. Editing in run-time is not supported.
|
||||
string, // Facility name: "Mfg" | "Trade" | "Power" | "Control" | "Reception" | "Office" | "Dorm"
|
||||
...
|
||||
],
|
||||
"drones": string, // Usage of drones, optional, by default "_NotUse"
|
||||
// "_NotUse"、"Money"、"SyntheticJade"、"CombatRecord"、"PureGold"、"OriginStone"、"Chip"
|
||||
"threshold": float, // Morale threshold with range [0, 1.0], optional, by default 0.3
|
||||
"replenish": bool, // Whether to replenish Originium Shard, optional, by default false
|
||||
}
|
||||
```
|
||||
|
||||
- `Visit`
|
||||
Visiting reception room of friends
|
||||
Settings are not supported.
|
||||
|
||||
- `Mall`
|
||||
Collecting Credits and auto-purchasing
|
||||
Will buy items in order following `buy_first` list, and buy other items from left to right ignoring items iin `blacklist`.
|
||||
|
||||
```jsonc
|
||||
// Corresponding task parameters
|
||||
{
|
||||
"shopping": bool, // Whether to buy items from the store, optional, by default false. Editing in run-time is not supported.
|
||||
"buy_first": [ // Items to be purchased with priority, optional. Editing in run-time is not supported.
|
||||
string, // Item name, e.g. "招聘许可" (Recruitment Permit), "龙门币" (LMD), etc.
|
||||
],
|
||||
"blacklist": [ // Blacklist, optional. Editing in run-time is not supported.
|
||||
string, // Item name, e.g. "加急许可" (Expedited Plan), "家具零件" (Furniture Part), etc.
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `Award`
|
||||
Collecting daily awards.
|
||||
Settings are not supported.
|
||||
|
||||
- `Roguelike`
|
||||
Integrated Strategies
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"mode": int, // Mode, optional, by default 0
|
||||
// 0 - Plays as much as you can
|
||||
// 1 - Exits after first level
|
||||
// 2 - Plays until trading
|
||||
}
|
||||
```
|
||||
|
||||
- `Copilot`
|
||||
Copilot auto-combat feature
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"stage_name": string, // Stage name, same as the `stage_name` field in JSON. Editing in run-time is not supported.
|
||||
"filename": string, // Filename and path of the task JSON, supporting absolute/relative paths. Editing in run-time is not supported.
|
||||
"formation": bool // Whether to "quick build", optional, by default false. Editing in run-time is not supported.
|
||||
}
|
||||
```
|
||||
|
||||
For more details about task JSON, please refer to [Task Schema](TASK_SCHEMA.md)
|
||||
|
||||
### `AsstSetTaskParams`
|
||||
|
||||
#### Prototype
|
||||
|
||||
```c++
|
||||
bool ASSTAPI AsstSetTaskParams(AsstHandle handle, TaskId id, const char* params);
|
||||
```
|
||||
|
||||
#### Description
|
||||
|
||||
Set task parameters
|
||||
|
||||
#### Return Value
|
||||
|
||||
- `bool`
|
||||
Whether the parameters are successfully set.
|
||||
|
||||
#### Parameter Description
|
||||
|
||||
- `AsstHandle handle`
|
||||
Instance handle
|
||||
- `TaskId task`
|
||||
Task ID, the return value of `AsstAppendTask`
|
||||
- `const char* params`
|
||||
Task parameter in JSON, same as `AsstAppendTask`
|
||||
For those fields that do not mention "Editing in run-time is not supported" can be changed during run-time. Otherwise these changes will be ignored when the task is running.
|
||||
70
docs/en/LINUX_TUTORIAL.md
Normal file
70
docs/en/LINUX_TUTORIAL.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Linux Compilation Tutorial
|
||||
|
||||
**The tutorial requires some basic knowledge about Linux OS!**
|
||||
|
||||
Though it is unclear why it needs to run in Linux... Anyway in case somebody needs it_(:з」∠)_
|
||||
|
||||
If you meet any other problems, please feel free to submit issue to us.
|
||||
|
||||
## Download and Compile 3rd-party Libraries
|
||||
|
||||
### Opencv
|
||||
|
||||
Please search the tutorial and install. Nothing to mention. The version `4.5.3` is confirmed to be able to use. Other versions should be OK as well, but `4.5.3` is recommended to keep it the same as the project and avoid some unnecessary problems. Installing `Opencv` itself is enough. `opencv_contrib` is not required.
|
||||
|
||||
### PaddleOCR
|
||||
|
||||
1. Use a hacked version: https://github.com/MistEO/PaddleOCR.
|
||||
2. Refer to [this tutorial](https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.3/deploy/cpp_infer#readme).
|
||||
3. [Download](https://paddleinference.paddlepaddle.org.cn/master/user_guides/download_lib.html) extra dependencies for `PaddlePaddle`. Both `avx` and `mkl` are recommended, which can improve the efficiency of calculation. However, if your CPU does not support them, you can choose compatible version of either `noavx` or `openblas` (new CPUs should support them, even AMD). `cuda` and `cudnn` are GPU libraries, but I haven't tried it on `PaddleOCR` yet. Feel free to try it out.
|
||||
4. If `cmake` cannot find `Opencv`, you can try editing [the finding path of Opencv](https://github.com/MistEO/PaddleOCR/blob/release/2.3/deploy/cpp_infer/CMakeLists.txt#L49).
|
||||
5. If you are using `MKL` version, you can change the [MKL Macro](https://github.com/MistEO/PaddleOCR/blob/release/2.3/deploy/cpp_infer/include/ocr_defines.h#L9) to `true` to improve performance.
|
||||
|
||||
Compilation flags for your reference
|
||||
|
||||
```bash
|
||||
cmake ../ -DPADDLE_LIB=/your_path/paddle_inference/ -DOpenCV_DIR=/your_path_to_opencv/ -DWITH_STATIC_LIB=OFF -DBUILD_SHARED=ON
|
||||
# If your device does not support MKL, you can add `-DWITH_MKL=OFF` flag, and download corresponding PaddlePaddle version.
|
||||
```
|
||||
|
||||
### zlib
|
||||
|
||||
In Ubuntu:
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt install zlib1g-dev
|
||||
sudo ldconfig
|
||||
```
|
||||
|
||||
If zlib does not exist in other distribution, you can try compiling from [source](https://github.com/madler/zlib).
|
||||
|
||||
## MeoAssistant
|
||||
|
||||
1. Copy the compiled 3rd-party library to `3rdparty/lib` or change `CMakeLists.txt` to indicate 3rd-party library path manually.
|
||||
2. The header files in `3rdparty/include/opencv` is version `4.5.3`. If you are using other versions, please notice there may be conflicts in header files (you can simply replace them with your `opencv` header files).
|
||||
3. Install `adb`, and change `resource/config.json` - `Custom.adb.path` to `"adb"`
|
||||
4. Copy resource files to the same folder of `libMeoAssitant.so`.
|
||||
|
||||
```sh
|
||||
cd tools
|
||||
sh ./update_resource.sh <YourBuildDir>
|
||||
```
|
||||
|
||||
5. Call by [Python interface](../src/Python/interface.py) or [C interface](../include/AsstCaller.h), requiring you to write some code.
|
||||
6. `cmake` can compile a demo for testing by adding `-DBUILD_TEST=ON` flag
|
||||
|
||||
## Integration Documentation
|
||||
|
||||
[~~Maybe not a doc~~](https://github.com/MistEO/MeoAssistantArknights/wiki)
|
||||
|
||||
### Python
|
||||
|
||||
Refer to the implementation of `__main__` in [Python demo](../src/Python/sample.py)
|
||||
|
||||
### C
|
||||
|
||||
Refer to the implementation of [TestCaller](../tools/TestCaller/main.cpp)
|
||||
|
||||
### C sharp
|
||||
|
||||
Refer to the implementation of [MeoAsstGui](../src/MeoAsstGui/Helper/AsstProxy.cs)
|
||||
78
docs/en/SIMULATOR_SUPPORT.md
Normal file
78
docs/en/SIMULATOR_SUPPORT.md
Normal file
@@ -0,0 +1,78 @@
|
||||
## Simulator Support
|
||||
|
||||
### Bluestack
|
||||
|
||||
Fully compatible. Need to turn on `Settings` - `Engine Settings` - `Allow ADB connection`.
|
||||
|
||||
### Bluestack International Version (Recommended)
|
||||
|
||||
Fully compatible. Need to turn on `Settings` - `Advanced` - `Android Debug Bridge`.
|
||||
|
||||
### Bluestack Hyper-V Version
|
||||
|
||||
Compatible.
|
||||
|
||||
- Turn on `Settings` - `Advanced` - `Android Debug Bridge`.
|
||||
- Bluestack Hyper-V port changes frequently. Here is a simple hack:
|
||||
1. Find `bluestacks.conf` in the installation location of the simulator.
|
||||
2. Launch MAA, which generates `gui.json`. Open it.
|
||||
3. Add a new field `Bluestacks.Config.Path`, with the value of the full path of `bluestacks.conf` (backslash should be escaped like `\\`).
|
||||
4. LinkStart!
|
||||
|
||||
### Nox
|
||||
|
||||
Fully compatible.
|
||||
|
||||
### Nox Android 9
|
||||
|
||||
Fully compatible.
|
||||
|
||||
### MuMu
|
||||
|
||||
Compatible but:
|
||||
|
||||
- Requires MAA to "Run as Administrator" to get ADB path and address (since MuMu runs as admin).
|
||||
- You can also fill in the ADB path and address if you do not wish to run as admin.
|
||||
- It has a chance that MAA may stuck at the main screen and prompt mission failed, which is probably related to the rendering method of MuMu. Recommend to change other simulator.
|
||||
|
||||
### MuMu Mobile Game Assistant
|
||||
|
||||
Incompatible. ADB port is not open.
|
||||
|
||||
### MuMu Android 9
|
||||
|
||||
Incompatible. ADB screenshot is black.
|
||||
|
||||
### Leidian
|
||||
|
||||
Compatible.
|
||||
|
||||
But the connection address will change between `127.0.0.1:5555` and `emulator-5554`, varies from device to device, or may change after restarting. Try another when one address is not available.
|
||||
|
||||
### Xiaoyao
|
||||
|
||||
Compatible, but some recognition error may occur.
|
||||
|
||||
### Tencent Mobile Game Assistant
|
||||
|
||||
Incompatible. ADB port is not open.
|
||||
|
||||
### Win11 WSA
|
||||
|
||||
Partially compatible.
|
||||
|
||||
- Need to connect with [Custom Connection](#custom-connection). Try `Legacy WSA` or `General Configuration` to connect.
|
||||
- Since WSA does not support changing resolution, please resize the window manually because this program supports 720p or higher `16:9` resolution better. (Or you can simply maximize the window if your monitor is 16:9.)
|
||||
- Sometimes the screenshot of WSA may be blank, causing recognition failure. So it is not recommended to use WSA.
|
||||
|
||||
### AVD
|
||||
|
||||
Compatible.
|
||||
|
||||
### Custom Connection
|
||||
|
||||
1. Download [adb](https://dl.google.com/android/repository/platform-tools-latest-windows.zip) and unzip.
|
||||
2. Go to `Settings` - `Connection Settings`, and fill in ADB path and address (IP+port is required, e.g. `127.0.0.1:5555`)
|
||||
|
||||
**Note:** Some features on mobile phone with non-`16:9` resolution is not stable, especially the Infrastructure. We are working in progress to make it compatible. `16:9` is the most recommended resolution since it is tested stable in most of the time.
|
||||
You can set resolution with `adb shell wm size` on your phone and change it back later.
|
||||
155
docs/en/TASK_SCHEMA.md
Normal file
155
docs/en/TASK_SCHEMA.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Task Schema
|
||||
|
||||
Usage of `resource/tasks.json` and description of each field
|
||||
|
||||
## Overview
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"TaskName" : { // Task name
|
||||
|
||||
"algorithm": "MatchTemplate", // Recognition algorithm, optional
|
||||
// MatchTemplate by default
|
||||
// - JustReturn: Proceed action without recognition
|
||||
// - MatchTemplate: Matching template image
|
||||
// - OcrDetect: OCR detection
|
||||
// - Hash: Hash calculation
|
||||
|
||||
"template": "xxx.png", // Available only when `algorithm` is `MatchTemplate`; Image file for matching, optional
|
||||
// "任务名.png" by default
|
||||
|
||||
"text": [ "接管作战", "代理指挥" ], // Available only when `algorithm` is `OcrDetect`; text to recognize, required, matched when any of the texts are found
|
||||
|
||||
"action": "ClickSelf", // Action after recognition, optional
|
||||
// DoNothing by default
|
||||
// - ClickSelf: Clicking the position recognized (random position within the region)
|
||||
// - ClickRand: Clicking any position in the screen
|
||||
// - DoNothing: Doing nothing
|
||||
// - Stop: Stopping current task
|
||||
// - ClickRect: Clicking in the specified rectangle. See the specificRect field, not recommended
|
||||
// - SwipeToTheLeft: Swiping to the left
|
||||
// - SwipeToTheRight: Swiping to the right
|
||||
|
||||
"sub": [ "SubTaskName1", "SubTaskName2" ],
|
||||
// Subtasks, optional. Will be executed in the order of the list after execution of the current task.
|
||||
// Subtasks can contain other subtasks. Pay attention to the infinite loop.
|
||||
|
||||
"subErrorIgnored": true, // Whether to ignore the error of the subtask, optional
|
||||
// `false` by default
|
||||
// `false` for not executing proceeding subtasks when one of the subtasks fails (considered as a failure of the current task).
|
||||
// `true` for ignoring subtask errors.
|
||||
|
||||
"next": [ "OtherTaskName1", "OtherTaskName2"],
|
||||
// Next tasks to be executed after the current task is finished, optional
|
||||
// Will be recognized from the first item of the list and execute the first matched one.
|
||||
// Empty list means to stop the task after the current task is finished.
|
||||
|
||||
"maxTimes": 10, // Maximum execution times, optional
|
||||
// Infinity by default
|
||||
// Proceeds with `exceedNext` if it exists; otherwise stops.
|
||||
|
||||
"exceededNext": [ "OtherTaskName1", "OtherTaskName2" ],
|
||||
// Tasks to be executed after reaching `maxTimes`, optional
|
||||
// Stops the task if empty; otherwise, proceeds with the tasks here in the list instead of `next`.
|
||||
|
||||
"preDelay": 1000, // Pre-delay of action in ms after recognition, optional; 0 by default
|
||||
"rearDelay": 1000, // Post-delay of action in ms after recognition, optional; 0 by default
|
||||
|
||||
"roi": [ 0, 0, 1280, 720], // Recognition region with the format of [ x, y, width, height ], optional
|
||||
// Auto-scaling based on 1280 * 720 resolution;[ 0, 0, 1280, 720 ] by default
|
||||
// Reducing the region has the effect of reducing performance consumption and speeding up the recognition.
|
||||
|
||||
"cache": true, // Whether the task uses cache, optional; `true` by default
|
||||
// After a successful recognition, subsequent recognition will be done only in the region cached, which has a significant performance enhancement.
|
||||
// Only for targets that do not change position. Please set it to `false` for targets with changing position.
|
||||
|
||||
"rectMove": [0, 0, 0, 0], // Target movements after recognition, optional, not recommended. Auto-scaling based on 1280 * 720 resolution.
|
||||
// E.g. Icon A is recognized but the target is some position beside A. You can set it to click the place beside it. It is suggested that it should recognize the target to click instead of using this field.
|
||||
|
||||
"reduceOtherTimes": [ "OtherTaskName1", "OtherTaskName2" ],
|
||||
// Reducing execution counter of other tasks after execution, optional
|
||||
// E.g. Using sanity potion means clicking the blue start button did not take effect so the counter of the starting task should be reduced by 1.
|
||||
|
||||
"specificRect": [ 100, 100, 50, 50],
|
||||
// Available only when `action` is `ClickRect`, indicating the position to click (random position within the region), required. Auto-scaling based on 1280 * 720 resolution.
|
||||
|
||||
/* Available only when `algorithm` is `MatchTemplate` */
|
||||
|
||||
"templThreshold": 0.8, // Threshold of image recognition, optional. Image is matched only when the similarity is greater than the threshold.
|
||||
// 0.8 by default. You can check it in the logs.
|
||||
|
||||
"maskRange": [ 1, 255 ], // Grayscale mask range, optional. E.g. fill in the region that does not require recognition with black colour, and set it to [ 1, 255 ] so that the black region is ignored.
|
||||
|
||||
|
||||
/* Available only when `algorithm` is `OcrDetect` */
|
||||
|
||||
"fullMatch": false, // Whether the text recognition is full match, optional. `false` by default.
|
||||
// `false` means substring matches as well. E.g.: `text: [ "开始" ]` matches "开始行动";
|
||||
// `true` means, e.g. it must match "开始" without other characters.
|
||||
|
||||
"ocrReplace": [ // Text replacement for common wrong recognition of OCR (supporting RegExp)
|
||||
[ "千员", "干员" ],
|
||||
[ ".+击干员", "狙击干员" ]
|
||||
]
|
||||
|
||||
/* Available only when `algorithm` is `Hash` */
|
||||
// Development in progress, only used in some special cases, not recommended
|
||||
// Todo
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
- Put the name of the task itself in `next` for looping, for example:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"Waiting": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [ "正在加载" ],
|
||||
"next": [
|
||||
"Succeed", // Matches "加载完成" first
|
||||
"Waiting" // Otherwise matches "正在加载"
|
||||
]
|
||||
},
|
||||
"Succeed": {
|
||||
"algorithm": "OcrDetect",
|
||||
"text": [ "加载完成" ],
|
||||
"next": [
|
||||
"OtherTask"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- The `JustReturn` field of `algorithm` is not recommended to set as a loop. Otherwise recognition will be always successful in some cases like adb disconnection.
|
||||
|
||||
- Tasks that are required to be executed N times can be copied N times with different names. For example:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"DoIt": {
|
||||
"next": [
|
||||
"DoItAgain"
|
||||
]
|
||||
},
|
||||
"DoItAgain": {
|
||||
"next": [
|
||||
"OtherTask"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Schema Check
|
||||
|
||||
This project provides JSON schema check for `tasks.json`. The schema file can be found at `docs/maa_tasks_schema.json`.
|
||||
|
||||
### Visual Studio
|
||||
|
||||
Visual Studio has been configured with `MeoAssistant.vcxporj`. Developers should be able to use it directly after loading the project.
|
||||
|
||||
### Visual Studio Code
|
||||
|
||||
Visual Studio Code has been configured with `.vscode/settings.json`. Developeres can open the **project folder** to use it, with better experience than Visual Studio.
|
||||
80
docs/en/USER_MANUAL.md
Normal file
80
docs/en/USER_MANUAL.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# MAA User Manual
|
||||
|
||||
## Introduction
|
||||
|
||||
### Operations
|
||||
|
||||
- If there is no stage you need, please click **blue start button** manually and select `current stage`.
|
||||
- When any of the `Sanity Potion`, `Originite Prime`, `Times` conditions are met, the task is considered completed and stops.
|
||||
- Example 1:check `Sanity Potion`: `999`, `Originite Prime`: `10`, `Times`: `1`. After **ONE** operation is completed, the task stops because `Times`: `1` is met.
|
||||
- Example 2:uncheck `Sanity Potion` and `Originite Prime`, and set `Times`: `100`. After sanity is used up (maybe several times), the condition `Sanity Potion` and `Originite Prime` is met, and the task stops.
|
||||
- Uploading operation statistics to [Penguin Stats](https://penguin-stats.cn/).
|
||||
- Custom Penguin Stats ID.
|
||||
- Recognizing and displaying drops.
|
||||
- Auto-reconnection after disconnection.
|
||||
- Auto-reconnection after 4 AM.
|
||||
- Annihilation support.
|
||||
- Supporting operator level-up.
|
||||
- Supporting auto-combat failure by abandoning the operation.
|
||||
|
||||
### Infrastructure
|
||||
|
||||
#### Shifting Strategy
|
||||
|
||||
Auto-calculate and choose the **optimal solution within a single facility**. Supports all general and special skill combination. Supports recognition of Battle Record, Pure Gold, Originium Shard, Chip, etc. for different operators.
|
||||
|
||||
#### Morale Threshold for Resting
|
||||
|
||||
Recognize the percentage of the Morale progress bar. When Morale decreases beyond some threshold, move the operator to the domitory.
|
||||
|
||||
#### Note
|
||||
|
||||
- The shifting strategy is based on the optimal solution within a single facility instead of multiple facilities. Combination such as: `Shamare+Tequila`, `Vermeil+Scene` within a single facility can be recognized correctly; while combination like `Rosmontis`, `Pinus Sylvestris` among facilities is not supported yet.
|
||||
- If `Usage of Drone` is selected with the option `Trading Post-LMD`, it will recognize `Shamare` and reserve it for her.
|
||||
- Operators of corresponding fraction will be selected when only one Clue is needed Reception Room; otherwise general operators will be chosen.
|
||||
- Reception Room will send out Clues only when your Clues are full. Three Clues will be send out at most. You can edit `SelectClue` - `maxTimes` field in `resource/tasks.json` to edit number of Clues sent if you want.
|
||||
- Due to the complexity of Control Center, only `Amiya`, `Swire`, `Kal'tsit`, `Team Rainbow` and other Morale+0.05 operators will be considered. To be improved in future.
|
||||
- Some alternate operators may have conflicts in Infrastructure. Please notice if there is "Operator conflict" warnings on the UI, and double check the Infrastructure to shift manually (e.g. some facilities may not have any operator).
|
||||
|
||||
### Recruitment Recognition
|
||||
|
||||
- Auto-recruitment and recruitment recognition are two different features!
|
||||
- Auto-recruitment supports using `Expedited Plan` to make it fully automated! Please set it in the settings.
|
||||
- Pop-up window when 5★, 6★ operators are recruited.
|
||||
|
||||
### Integrated Strategy (I.S.) Support
|
||||
|
||||
- Three options in the settings
|
||||
|
||||
- Plays as much as you can: for getting candles.
|
||||
- Exits after first level: the most efficient mode for getting Originium Ingots. Easy mode is recommended.
|
||||
- Plays until trading: for getting both items.
|
||||
|
||||
- I.S. now supports recognition of operators and levels, and can choose an optimal solution of operators and skills.
|
||||
- Supports auto-reconnecting after disconnection, and replaying after 4 AM.
|
||||
- The program will abandon the operation and retry if it is stuck by some bug. If it is stuck frequently at some place and has severe impact on efficiency, please submit an issue to us.
|
||||
|
||||
### Share Your Tasks
|
||||
|
||||
Welcome to QQ Group: 912322156
|
||||
|
||||
#### Load Tasks
|
||||
|
||||
- Please run it on the screen with `Start Operation` button.
|
||||
- If you need to make your own build manually, turn off `auto build` to do so.
|
||||
|
||||
#### Create Tasks
|
||||
|
||||
- A tool for creating tasks is provided in the directory of EXE file. See also: [Task schema documenatation](TASK_SCHEMA.md) for help.
|
||||
- How to get map coordinates: start an operation after filling in `stage_name`. A file named `map.png` will be generated for your reference. Features like displaying map on the creator tool will be supported in future.
|
||||
- Drill plan is recommended for testing.
|
||||
- If the name of operator is not recognized correctly, check the log `asst.log` to see what is the recognition result, and edit `resource/tasks.json` - `CharsNameOcrReplace` to replace it.
|
||||
- It is recommended to write your own name, video walkthrough URL, or other things that you think helpful in the description.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
- Tasks order can be changed on the UI. So can the shifting order in the infrastructure.
|
||||
- All clicking event is randomized within a region, following Poisson distribution (higher probability at the center, lower probability around).
|
||||
- Developed in C++, the core algorithm supports multi-level cache, in order to reduce CPU and memory usage as much as possible.
|
||||
- Our software supports auto-update ✿✿ヽ(°▽°)ノ✿ Beta-testers can try beta versions, which updates faster and less buggy (maybe).
|
||||
- If auto-update fails, you can download manually and put the ZIP file under the same directory. The update will start automatically.
|
||||
@@ -1559,7 +1559,7 @@
|
||||
"desc": "进驻人力办公室时,人脉资源的联络速度+45%,心情每小时消耗+2",
|
||||
"template": "Bskill_hire_skgoat.png",
|
||||
"efficient": {
|
||||
"all": 44.9
|
||||
"all": 39.9
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1493,7 +1493,7 @@
|
||||
"TodaysSupplies",
|
||||
"Stop"
|
||||
],
|
||||
"rearDelay": 1000
|
||||
"rearDelay": 3000
|
||||
},
|
||||
"TodaysSupplies": {
|
||||
"algorithm": "OcrDetect",
|
||||
@@ -2552,7 +2552,7 @@
|
||||
150
|
||||
],
|
||||
"preDelay": 500,
|
||||
"rearDelay": 500
|
||||
"rearDelay": 1500
|
||||
},
|
||||
"CreditShop-NoMoney": {
|
||||
"algorithm": "OcrDetect",
|
||||
@@ -2998,8 +2998,10 @@
|
||||
165,
|
||||
149
|
||||
],
|
||||
"rearDelay": 1000,
|
||||
"next": [
|
||||
"ReplenishToMaxConfirm"
|
||||
"ReplenishToMaxConfirm",
|
||||
"Stop"
|
||||
]
|
||||
},
|
||||
"ReplenishToMaxConfirm": {
|
||||
@@ -3966,6 +3968,7 @@
|
||||
],
|
||||
"next": [
|
||||
"InfrastClueFriendNew",
|
||||
"InfrastClueSelfFull",
|
||||
"CloseCluePage",
|
||||
"ReceptionFlag"
|
||||
]
|
||||
@@ -4443,9 +4446,9 @@
|
||||
"action": "ClickRect",
|
||||
"specificRect": [
|
||||
15,
|
||||
690,
|
||||
710,
|
||||
80,
|
||||
30
|
||||
10
|
||||
]
|
||||
},
|
||||
"BattleQuickFormationConfirm": {
|
||||
|
||||
@@ -36,5 +36,9 @@ bool asst::AbstractConfiger::load(const std::string& filename)
|
||||
m_last_error = std::string("json field error ") + e.what();
|
||||
return false;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
m_last_error = std::string("json field error ") + e.what();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,12 @@ namespace asst
|
||||
log(level, std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void warn(Args&&... args)
|
||||
{
|
||||
std::string_view level = "WRN";
|
||||
log(level, std::forward<Args>(args)...);
|
||||
}
|
||||
template <typename... Args>
|
||||
inline void error(Args&&... args)
|
||||
{
|
||||
std::string_view level = "ERR";
|
||||
@@ -144,7 +150,7 @@ namespace asst
|
||||
|
||||
if (!m_ofs.is_open()) {
|
||||
m_ofs = std::ofstream(m_log_filename, std::ios::out | std::ios::app);
|
||||
}
|
||||
}
|
||||
#ifdef ASST_DEBUG
|
||||
stream_args(m_ofs, buff, args...);
|
||||
#else
|
||||
@@ -154,7 +160,7 @@ namespace asst
|
||||
#ifdef ASST_DEBUG
|
||||
stream_args<true>(std::cout, buff, std::forward<Args>(args)...);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template <bool ToGbk = false, typename T, typename... Args>
|
||||
inline void stream_args(std::ostream& os, T&& first, Args&&... rest)
|
||||
@@ -187,7 +193,7 @@ namespace asst
|
||||
os << first << " "; // Don't fucking use gbk in linux
|
||||
#endif
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
inline static std::string m_dirname;
|
||||
std::mutex m_trace_mutex;
|
||||
|
||||
@@ -26,8 +26,8 @@ bool asst::MallTask::set_params(const json::value& params)
|
||||
if (params.contains("buy_first") && params.at("buy_first").is_array()) {
|
||||
std::vector<std::string> buy_first;
|
||||
for (auto& name : params.at("buy_first").as_array()) {
|
||||
std::string name_str = name.as_string();
|
||||
if (!name_str.empty()) {
|
||||
if (std::string name_str = name.as_string();
|
||||
!name_str.empty()) {
|
||||
buy_first.emplace_back(name_str);
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,10 @@ bool asst::MallTask::set_params(const json::value& params)
|
||||
if (params.contains("blacklist") && params.at("blacklist").is_array()) {
|
||||
std::vector<std::string> shopping_list;
|
||||
for (auto& name : params.at("blacklist").as_array()) {
|
||||
shopping_list.emplace_back(name.as_string());
|
||||
if (std::string name_str = name.as_string();
|
||||
!name_str.empty()) {
|
||||
shopping_list.emplace_back(name.as_string());
|
||||
}
|
||||
}
|
||||
m_shopping_task_ptr->set_black_list(std::move(shopping_list));
|
||||
}
|
||||
|
||||
@@ -98,22 +98,20 @@ void asst::MatchImageAnalyzer::set_task_info(MatchTaskInfo task_info) noexcept
|
||||
}
|
||||
bool asst::MatchImageAnalyzer::match_templ(const cv::Mat templ)
|
||||
{
|
||||
cv::Mat matched;
|
||||
|
||||
if (m_roi.x < 0) {
|
||||
Log.info("roi is out of range", m_roi.to_string());
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.x = 0;
|
||||
}
|
||||
if (m_roi.y < 0) {
|
||||
Log.info("roi is out of range", m_roi.to_string());
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.y = 0;
|
||||
}
|
||||
if (m_roi.x + m_roi.width > m_image.cols) {
|
||||
Log.info("roi is out of range", m_roi.to_string());
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.width = m_image.cols - m_roi.x;
|
||||
}
|
||||
if (m_roi.y + m_roi.height > m_image.rows) {
|
||||
Log.info("roi is out of range", m_roi.to_string());
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.height = m_image.rows - m_roi.y;
|
||||
}
|
||||
|
||||
@@ -124,6 +122,8 @@ bool asst::MatchImageAnalyzer::match_templ(const cv::Mat templ)
|
||||
"templ size:", templ.cols, templ.rows);
|
||||
return false;
|
||||
}
|
||||
|
||||
cv::Mat matched;
|
||||
if (m_mask_range.first == 0 && m_mask_range.second == 0) {
|
||||
cv::matchTemplate(image_roi, templ, matched, cv::TM_CCOEFF_NORMED);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
bool asst::OcrImageAnalyzer::analyze()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
m_ocr_result.clear();
|
||||
|
||||
std::vector<TextRectProc> preds_vec;
|
||||
@@ -67,6 +69,23 @@ bool asst::OcrImageAnalyzer::analyze()
|
||||
}
|
||||
}
|
||||
if (need_local) {
|
||||
if (m_roi.x < 0) {
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.x = 0;
|
||||
}
|
||||
if (m_roi.y < 0) {
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.y = 0;
|
||||
}
|
||||
if (m_roi.x + m_roi.width > m_image.cols) {
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.width = m_image.cols - m_roi.x;
|
||||
}
|
||||
if (m_roi.y + m_roi.height > m_image.rows) {
|
||||
Log.warn("roi is out of range", m_roi.to_string());
|
||||
m_roi.height = m_image.rows - m_roi.y;
|
||||
}
|
||||
|
||||
m_ocr_result = Resrc.ocr().recognize(m_image, m_roi, all_pred, m_without_det);
|
||||
}
|
||||
//log.trace("ocr result", m_ocr_result);
|
||||
|
||||
@@ -18,6 +18,13 @@ bool asst::RoguelikeSkillSelectionImageAnalyzer::analyze()
|
||||
|
||||
const auto& flags = flag_analyzer.get_result();
|
||||
|
||||
if (flags.size() > 13) {
|
||||
// https://github.com/MaaAssistantArknights/MaaAssistantArknights/issues/669
|
||||
// 不知道为什么会匹配出来一堆结果,得分完全相同,坐标间隔还特别有规律。这种情况直接报错然后重试
|
||||
Log.error("Too many flags");
|
||||
return false;
|
||||
}
|
||||
|
||||
int unknow_index = 0;
|
||||
for (const auto& flag : flags) {
|
||||
std::string name = name_analyze(flag.rect);
|
||||
|
||||
@@ -24,7 +24,7 @@ asst::RoguelikeTask::RoguelikeTask(AsstCallback callback, void* callback_arg)
|
||||
m_recruit_task_ptr->set_retry_times(2);
|
||||
|
||||
m_skill_task_ptr = m_roguelike_task_ptr->regiseter_plugin<RoguelikeSkillSelectionTaskPlugin>();
|
||||
m_skill_task_ptr->set_retry_times(0);
|
||||
m_skill_task_ptr->set_retry_times(3);
|
||||
|
||||
// 这个任务如果卡住会放弃当前的肉鸽并重新开始,所以多添加一点。先这样凑合用
|
||||
for (int i = 0; i != 10000; ++i) {
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace MeoAsstGui
|
||||
public class ViewStatusStorage
|
||||
{
|
||||
private static readonly string _configFilename = System.Environment.CurrentDirectory + "\\gui.json";
|
||||
private static readonly string _configBakFilename = System.Environment.CurrentDirectory + "\\gui.json.bak";
|
||||
private static JObject _viewStatus = new JObject();
|
||||
|
||||
public static string Get(string key, string defalut_value)
|
||||
@@ -40,7 +41,7 @@ namespace MeoAsstGui
|
||||
Save();
|
||||
}
|
||||
|
||||
public static bool Load()
|
||||
public static bool Load(bool withRestore = true)
|
||||
{
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
@@ -48,13 +49,27 @@ namespace MeoAsstGui
|
||||
{
|
||||
string jsonStr = File.ReadAllText(_configFilename);
|
||||
|
||||
if (jsonStr.Length <= 2 && File.Exists(_configBakFilename))
|
||||
{
|
||||
File.Copy(_configBakFilename, _configFilename, true);
|
||||
jsonStr = File.ReadAllText(_configFilename);
|
||||
}
|
||||
|
||||
// 文件存在但为空,会读出来一个null,感觉c#这库有bug,如果是null 就赋值一个空JObject
|
||||
_viewStatus = (JObject)JsonConvert.DeserializeObject(jsonStr) ?? new JObject();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_viewStatus = new JObject();
|
||||
return false;
|
||||
if (withRestore && File.Exists(_configBakFilename))
|
||||
{
|
||||
File.Copy(_configBakFilename, _configFilename, true);
|
||||
return Load(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
_viewStatus = new JObject();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -69,9 +84,17 @@ namespace MeoAsstGui
|
||||
{
|
||||
try
|
||||
{
|
||||
using (StreamWriter sw = new StreamWriter(_configFilename))
|
||||
var jsonStr = _viewStatus.ToString();
|
||||
if (jsonStr.Length > 2)
|
||||
{
|
||||
sw.Write(_viewStatus.ToString());
|
||||
using (StreamWriter sw = new StreamWriter(_configFilename))
|
||||
{
|
||||
sw.Write(jsonStr);
|
||||
}
|
||||
if (new System.IO.FileInfo(_configFilename).Length > 2)
|
||||
{
|
||||
File.Copy(_configFilename, _configBakFilename, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace MeoAsstGui
|
||||
//LogItemViewModels.Insert(0, new LogItemViewModel(time + content, color, weight));
|
||||
}
|
||||
|
||||
public void AddLogWithUrl(string content,string url, string color = "Gray", string weight = "Regular")
|
||||
public void AddLogWithUrl(string content, string url, string color = "Gray", string weight = "Regular")
|
||||
{
|
||||
LogItemViewModels.Add(new LogItemViewModel(content, color, weight));
|
||||
//LogItemViewModels.Insert(0, new LogItemViewModel(time + content, color, weight));
|
||||
@@ -70,7 +70,7 @@ namespace MeoAsstGui
|
||||
LogItemViewModels.Clear();
|
||||
}
|
||||
|
||||
private string _filename;
|
||||
private string _filename = "";
|
||||
|
||||
public string Filename
|
||||
{
|
||||
@@ -232,9 +232,16 @@ namespace MeoAsstGui
|
||||
|
||||
const string _newfilename = "resource/_temp_copilot.json";
|
||||
File.WriteAllText(_newfilename, data.ToString());
|
||||
asstProxy.AsstStartCopilot(data["stage_name"].ToString(), _newfilename, Form);
|
||||
Idle = false;
|
||||
AddLog("Star Burst Stream!");
|
||||
bool ret = asstProxy.AsstStartCopilot(data["stage_name"].ToString(), _newfilename, Form);
|
||||
if (ret)
|
||||
{
|
||||
Idle = false;
|
||||
AddLog("Star Burst Stream!");
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLog("读取 JSON 作业文件出错\n请检查文件内容", "darkred");
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace MeoAsstGui
|
||||
//Items.Add(ivm);
|
||||
Items.Add(cvm);
|
||||
Items.Add(svm);
|
||||
svm.UpdateWindowTitle(); // 在标题栏上显示模拟器和IP端口 必须在 Items.Add(svm)之后执行。
|
||||
svm.UpdateWindowTitle(); // 在标题栏上显示模拟器和IP端口 必须在 Items.Add(svm)之后执行。
|
||||
ActiveItem = tvm;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace MeoAsstGui
|
||||
await task;
|
||||
}
|
||||
}
|
||||
private string _windowTitle;
|
||||
private string _windowTitle = "MaaAssistantArknights";
|
||||
public string WindowTitle
|
||||
{
|
||||
get => _windowTitle;
|
||||
|
||||
@@ -37,6 +37,22 @@ namespace MeoAsstGui
|
||||
InitTimer();
|
||||
}
|
||||
|
||||
public void ShowButton()
|
||||
{
|
||||
Visible = Visibility.Visible;
|
||||
Hibernate = true;
|
||||
}
|
||||
|
||||
private Visibility _visible = Visibility.Collapsed;
|
||||
public Visibility Visible
|
||||
{
|
||||
get { return _visible; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _visible, value);
|
||||
}
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Timer _timer = new System.Windows.Forms.Timer();
|
||||
|
||||
private void InitTimer()
|
||||
@@ -421,6 +437,14 @@ namespace MeoAsstGui
|
||||
System.Diagnostics.Process.Start("shutdown.exe", "-a");
|
||||
}
|
||||
}
|
||||
if (Hibernate)
|
||||
{
|
||||
System.Diagnostics.Process.Start("shutdown.exe", "-h");
|
||||
}
|
||||
if (Suspend)
|
||||
{
|
||||
System.Diagnostics.Process.Start("rundll32.exe", "powrprof.dll,SetSuspendState 0,1,0");
|
||||
}
|
||||
}
|
||||
|
||||
private bool _idle = false;
|
||||
@@ -444,6 +468,46 @@ namespace MeoAsstGui
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _shutdown, value);
|
||||
|
||||
if (value)
|
||||
{
|
||||
Hibernate = false;
|
||||
Suspend = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _hibernate = false; // 休眠
|
||||
|
||||
public bool Hibernate
|
||||
{
|
||||
get { return _hibernate; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _hibernate, value);
|
||||
|
||||
if (value)
|
||||
{
|
||||
Shutdown = false;
|
||||
Suspend = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool _suspend = false; // 待机
|
||||
|
||||
public bool Suspend
|
||||
{
|
||||
get { return _suspend; }
|
||||
set
|
||||
{
|
||||
SetAndNotify(ref _suspend, value);
|
||||
|
||||
if (value)
|
||||
{
|
||||
Shutdown = false;
|
||||
Hibernate = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,26 +19,47 @@
|
||||
<Grid Grid.Column="0" Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="60" />
|
||||
<RowDefinition Height="40" />
|
||||
<RowDefinition Height="60" />
|
||||
<RowDefinition Height="60" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox x:Name="TaskList" Grid.Row="0" Width="200" Margin="0,10,0,0" HorizontalAlignment="Center"
|
||||
<Border BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" CornerRadius="4" MaxWidth="260">
|
||||
<Grid Grid.Row="0" Margin="0" Width="200">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="40" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<ListBox x:Name="TaskList" Grid.Row="0" Grid.ColumnSpan="2" Width="200" Margin="0,10,0,0" HorizontalAlignment="Center"
|
||||
dd:DragDrop.IsDragSource="{Binding Idle}" dd:DragDrop.IsDropTarget="{Binding Idle}"
|
||||
ItemsSource="{Binding Path=TaskItemViewModels}">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!--<TextBlock Style="{StaticResource TextBlockDefault}" Text="{Binding ID}" />
|
||||
ItemsSource="{Binding Path=TaskItemViewModels}" BorderThickness="0">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<!--<TextBlock Style="{StaticResource TextBlockDefault}" Text="{Binding ID}" />
|
||||
<TextBlock Style="{StaticResource TextBlockDefault}" Text=". " />-->
|
||||
<CheckBox IsChecked="{Binding IsChecked}" IsHitTestVisible="{Binding ElementName=TaskList, Path=DataContext.Idle}" Content="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<Button Grid.Row="1" Command="{s:Action SelectedAll}" IsEnabled="{Binding Idle}" Content="全选" HorizontalAlignment="Center" Width="100" Height="30" Margin="-100,0,0,0" VerticalAlignment="Top" />
|
||||
<Button Grid.Row="1" Command="{s:Action InverseSelected}" IsEnabled="{Binding Idle}" Content="反选" HorizontalAlignment="Center" Width="100" Height="30" Margin="100,0,0,0" VerticalAlignment="Top" />
|
||||
<CheckBox Grid.Row="1" IsChecked="{Binding Shutdown}" Content="自动关机" HorizontalAlignment="Center" Margin="0,34,0,0" />
|
||||
<CheckBox IsChecked="{Binding IsChecked}" IsHitTestVisible="{Binding ElementName=TaskList, Path=DataContext.Idle}" Content="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<Button Grid.Row="1" Grid.Column="0" Command="{s:Action SelectedAll}" IsEnabled="{Binding Idle}" Content="全选" Width="90" Height="30" VerticalAlignment="Top" />
|
||||
<Button Grid.Row="1" Grid.Column="1" Command="{s:Action InverseSelected}" IsEnabled="{Binding Idle}" Content="反选" Width="90" Height="30" VerticalAlignment="Top" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment ="Center">
|
||||
<CheckBox IsChecked="{Binding Shutdown}" Content="自动关机" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<CheckBox.InputBindings>
|
||||
<KeyBinding Key="H" Command="{s:Action ShowButton}"/>
|
||||
</CheckBox.InputBindings>
|
||||
</CheckBox>
|
||||
<CheckBox IsChecked="{Binding Hibernate}" Content="休眠" Visibility="{Binding Visible}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
<CheckBox IsChecked="{Binding Suspend}" Content="待机" Visibility="{Binding Visible}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
|
||||
<Button Grid.Row="2" Command="{s:Action LinkStart}" IsEnabled="{Binding Idle}" Content="LinkStart !" HorizontalAlignment="Center" Width="120" Height="50" Margin="5" />
|
||||
<Button Grid.Row="3" Command="{s:Action Stop}" Content="停止" HorizontalAlignment="Center" Width="120" Height="50" Margin="5" />
|
||||
</Grid>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// 全局JSON数据
|
||||
const data = {};
|
||||
// 必填字段可以放在这里,预设空值
|
||||
const data = {
|
||||
actions: [],
|
||||
};
|
||||
|
||||
// 模板
|
||||
const input_text = () => {
|
||||
|
||||
Reference in New Issue
Block a user