mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-20 10:57:45 +08:00
Merge branch 'MaaAssistantArknights:dev' into sami
This commit is contained in:
65
CHANGELOG.md
65
CHANGELOG.md
@@ -1,60 +1,29 @@
|
||||
## v4.24.0-beta.5
|
||||
## v4.24.0-rc.1
|
||||
|
||||
### 新增
|
||||
|
||||
- 肉鸽烧开水模式增加凹开局直升 (#6443) @Lancarus
|
||||
- 肉鸽适配高规格分队开局 (#6436) @Lancarus
|
||||
- 开始唤醒-账号切换新增手动切换,可单独执行开始唤醒流程 (#6433) @status102
|
||||
- 如果任务流程中勾选了刷理智,则在任务链结束时提供一个理智回满的预测时间 (#6456) @status102
|
||||
- macOS 国际服允许添加生息演算任务 @hguandl
|
||||
- 新增领取邮件功能 (#6438) @broken-paint
|
||||
|
||||
### 改进
|
||||
|
||||
- 投资达到上限后退出到肉鸽主界面 (#6435) @zzyyyl
|
||||
- 优化傀影招募策略 (#6476) @Lancarus
|
||||
- 激活自动战斗-战斗列表时将同时激活自动编队,调整自动战斗UI (#6448) @status102
|
||||
- 优化傀影肉鸽招募和商店逻辑 (#6447) @Lancarus
|
||||
- 稍微优化下自动战斗界面 ui @moomiji
|
||||
- 优化 自动战斗-战斗列表 跳过战斗后剧情的逻辑 (#6430) @status102
|
||||
- 优化萨米招募逻辑 (#6422) @Lancarus
|
||||
- 稍微优化下自动战斗界面 ui @ABA2396
|
||||
- 水月肉鸽:增加支援道具,新干员分组,优化大君遗脉策略 (#6372) @Yumi0606
|
||||
- 在非烧水模式,取消刷直升按钮 (#6484) @mole828
|
||||
- optimize time diff format in sanity report (#6512) @KevinT3Hu
|
||||
|
||||
### 修复
|
||||
|
||||
- 增加延迟以提高刷理智-当前理智识别成功率 (#6402) @status102
|
||||
- 修复 sanity_report == null 的问题 @zzyyyl
|
||||
- 加工站不设置干员时,直接报错并返回 @MistEO
|
||||
- 修复水月肉鸽卡在藏品 (#6464) @mole828
|
||||
- 修复 debug 模式下 tasks.json 检查未通过时的访问越界问题 @zzyyyl
|
||||
- 修复网络波动造成的使用理智药不清理智问题 @zzyyyl
|
||||
- 修复自动战斗-战斗列表的导航失效问题 (#6413) @status102
|
||||
- 修复Status缓存跨任务清理在任务链正常完成情况下失效的错误 (#6428) @status102
|
||||
- 修复外部通知错误 (#6414) @LiamSho
|
||||
- 修复资源读取错误,修复错误的界面提示 @ABA2396
|
||||
- 修复资源更新toast笔误 @MistEO
|
||||
- 通过进程名关闭蓝叠时如果模拟器个数超过1个则放弃关闭 @ABA2396
|
||||
- 自动战斗跳过“以下干员出战后将被禁用,是否继续?”对话框 #4917 #4694 #5351 (#6492) @Hydrogina
|
||||
- 自动战斗-自动编队-补充低信赖干员: 修正补充顺序,避免在极端情况下补充错误 (#6499) @status102
|
||||
- 尝试修复肉鸽卡在招募界面 (#6516) @Lancarus
|
||||
- 自动战斗-战斗列表,补充突袭结算图,修复从缓存文件夹添加作业时报错 (#6497) @status102
|
||||
- 修复凹直升功能造成的卡在招募立绘等bug (#6502) @Lancarus
|
||||
- 删掉多余的模板图片 @zzyyyl
|
||||
- 🐞 fix(Java-HTTP): 修复Java-HTTP api的编译问题 (#6490) @gylove1994
|
||||
|
||||
### 其他
|
||||
|
||||
- 基建换班-编组缓存 使用value_or替代empty检查 (#6404) @status102
|
||||
- 更新qodana配置 (#6465) @hxdnshx
|
||||
- gui.log 在启动时记录当前版本 @ABA2396
|
||||
- 在Python脚本中添加活动关导航下载与加载的示例 (#3916) (#6451) @ZhaoZuohong
|
||||
- 删除多余的空任务 @zzyyyl
|
||||
- debug: 增加一项多余空任务的检查 @zzyyyl
|
||||
- fix algorithm error warning @Constrat
|
||||
- reordered objects, following zh-cn @Constrat
|
||||
- removed duplicate operator @Constrat
|
||||
- Alter Operators ^$ regex fix Yato alter, Noir alter, Terra Research ident. @Constrat
|
||||
- 无配置字段时储存默认值 @ABA2396
|
||||
- 全局选项设置减少嵌套,增加日志 @ABA2396
|
||||
|
||||
### For overseas
|
||||
|
||||
#### YostarEN
|
||||
|
||||
- EN SSReopen-XX adaptation @Constrat
|
||||
- EN Guide Ahead navigation @Constrat
|
||||
- 修复 EN 任务 `BattleQuickFormationFilter-Cost` @zzyyyl
|
||||
- 修复 EN 生息演算任务 `Reclamation@ManufactureStatus` roi 越界的问题 @zzyyyl
|
||||
- 优化部分 WPF 代码 (#6510) @ABA2396 @zzyyyl
|
||||
- 优化 wpf 代码 (#6504) @zzyyyl
|
||||
- i18n: at on in date time @Constrat
|
||||
- debug: debug 模式下增加一项可省略模板任务名的检查 @zzyyyl
|
||||
- 文档杂项修改 (#6485) @Rbqwow
|
||||
- Update 3.5-肉鸽辅助协议.md @Lancarus
|
||||
|
||||
@@ -8,12 +8,15 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=arkplanner/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=asnipe/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bilibili/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluestacks/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=desp/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=findstr/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gacha/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hwnd/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Infrast/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Inited/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Lolicon/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=luestacks/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=netstat/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=oper/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=opers/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -27,5 +30,6 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Roguelike/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rsnipe/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Todays/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=txwy/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=XYAZ/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=_0020_003D_0020stri/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
@@ -43,7 +43,11 @@ AsstTaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const cha
|
||||
"enable": bool, // 是否启用本任务,可选,默认为 true
|
||||
"client_type": string, // 客户端版本,可选,默认为空
|
||||
// 选项:"Official" | "Bilibili" | "txwy" | "YoStarEN" | "YoStarJP" | "YoStarKR"
|
||||
"start_game_enabled": bool // 是否自动启动客户端,可选,默认不启动
|
||||
"start_game_enabled": bool, // 是否自动启动客户端,可选,默认不启动
|
||||
"account_name": string // 切换账号,可选,默认为当前账号
|
||||
// 仅支持切换至已登录的账号,使用登录名进行查找,保证输入内容在所有已登录账号唯一即可
|
||||
// 官服:123****4567,可输入 123****4567、4567、123、3****4567
|
||||
// B服:张三,可输入 张三、张、三
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -43,7 +43,11 @@ AsstTaskId ASSTAPI AsstAppendTask(AsstHandle handle, const char* type, const cha
|
||||
"enable": bool, // 是否啟用本任務,可選,預設為 true
|
||||
"client_type": string, // 用戶端版本,可選,預設為空
|
||||
// 選項:"Official" | "Bilibili" | "txwy" | "YoStarEN" | "YoStarJP" | "YoStarKR"
|
||||
"start_game_enabled": bool // 是否自動啟動用戶端,可選,預設不啟動
|
||||
"start_game_enabled": bool, // 是否自動啟動用戶端,可選,預設不啟動
|
||||
"account_name": string // 切換賬號,可選,預設為當前賬號
|
||||
// 僅支持切換至已登錄的賬號,使用登錄名進行查找,保證輸入內容在所有已登錄賬號唯一即可
|
||||
// 官服:123****4567,可輸入 123****4567、4567、123、3****4567
|
||||
// B服:張三,可輸入 張三、張、三
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -8242,6 +8242,15 @@
|
||||
100
|
||||
]
|
||||
},
|
||||
"StageDrops-Stars-Adverse": {
|
||||
"templThreshold": 0.8,
|
||||
"roi": [
|
||||
70,
|
||||
285,
|
||||
90,
|
||||
95
|
||||
]
|
||||
},
|
||||
"DepotMatchData": {
|
||||
"template": "empty.png",
|
||||
"templThreshold": 0.6,
|
||||
@@ -13250,7 +13259,8 @@
|
||||
"action": "DoNothing",
|
||||
"reduceOtherTimes": [],
|
||||
"next": [
|
||||
"Copilot@StageDrops-Stars-3"
|
||||
"Copilot@StageDrops-Stars-3",
|
||||
"Copilot@StageDrops-Stars-Adverse"
|
||||
]
|
||||
},
|
||||
"Copilot@StageDrops-Stars-3": {
|
||||
@@ -13261,6 +13271,14 @@
|
||||
"Copilot@ClickCornerUntilStartButton"
|
||||
]
|
||||
},
|
||||
"Copilot@StageDrops-Stars-Adverse": {
|
||||
"Doc": "如果没有三星就终止",
|
||||
"template": "StageDrops-Stars-Adverse.png",
|
||||
"action": "DoNothing",
|
||||
"next": [
|
||||
"Copilot@ClickCornerUntilStartButton"
|
||||
]
|
||||
},
|
||||
"Copilot@ClickCornerBeforeThreeStars": {
|
||||
"Doc": "三星之前",
|
||||
"baseTask": "Copilot@ClickCornerUntilStartButton",
|
||||
|
||||
BIN
resource/template/StageDrops-Stars-Adverse.png
Normal file
BIN
resource/template/StageDrops-Stars-Adverse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
@@ -422,11 +422,12 @@ void Assistant::working_proc()
|
||||
if (m_tasks_list.empty()) {
|
||||
callback_json["finished_tasks"] = json::array(finished_tasks);
|
||||
|
||||
const auto& sanity_str = status()->get_str(Status::FightSanityReport);
|
||||
if (sanity_str) {
|
||||
auto sanity_array = json::array(json::parse(*sanity_str).value_or(json::value(json::array())));
|
||||
// ["100/135", "2023-09-01 09:31:53.527"]
|
||||
callback_json["sanity"] = sanity_array;
|
||||
if (auto sanity_report = status()->get_str(Status::FightSanityReport);
|
||||
sanity_report && !sanity_report.value().empty()) {
|
||||
if (auto report_json = json::parse(sanity_report.value()); report_json) {
|
||||
// { "current_sanity": 100, "max_sanity": 135, "report_time": "2023-09-01 09:31:53.527" }
|
||||
callback_json["sanity_report"] = report_json.value();
|
||||
}
|
||||
}
|
||||
|
||||
append_callback(AsstMsg::AllTasksCompleted, callback_json);
|
||||
|
||||
@@ -739,6 +739,11 @@ asst::TaskData::taskptr_t asst::TaskData::generate_match_task_info(const std::st
|
||||
default_ptr = default_match_task_info_ptr;
|
||||
}
|
||||
auto match_task_info_ptr = std::make_shared<MatchTaskInfo>();
|
||||
#ifdef ASST_DEBUG
|
||||
if (task_json.get("template", "") == name + ".png") {
|
||||
Log.warn("template name of task", name, "could be omitted.");
|
||||
}
|
||||
#endif
|
||||
// template 留空时不从模板任务继承
|
||||
match_task_info_ptr->templ_name = task_json.get("template", name + ".png");
|
||||
m_templ_required.emplace(match_task_info_ptr->templ_name);
|
||||
@@ -772,7 +777,6 @@ asst::TaskData::taskptr_t asst::TaskData::generate_ocr_task_info([[maybe_unused]
|
||||
Log.warn("Ocr task", name, "has implicit empty text.");
|
||||
}
|
||||
#endif
|
||||
|
||||
ocr_task_info_ptr->full_match = task_json.get("fullMatch", default_ptr->full_match);
|
||||
ocr_task_info_ptr->is_ascii = task_json.get("isAscii", default_ptr->is_ascii);
|
||||
ocr_task_info_ptr->without_det = task_json.get("withoutDet", default_ptr->without_det);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "SanityBeforeStagePlugin.h"
|
||||
|
||||
#include <charconv>
|
||||
#include <regex>
|
||||
|
||||
#include "Config/TaskData.h"
|
||||
@@ -33,7 +34,7 @@ bool asst::SanityBeforeStagePlugin::_run()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
get_sanity();
|
||||
get_sanity_before_stage();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -41,7 +42,7 @@ bool asst::SanityBeforeStagePlugin::_run()
|
||||
/// <summary>
|
||||
/// 获取 当前理智/最大理智
|
||||
/// </summary>
|
||||
void asst::SanityBeforeStagePlugin::get_sanity()
|
||||
void asst::SanityBeforeStagePlugin::get_sanity_before_stage()
|
||||
{
|
||||
LogTraceFunction;
|
||||
|
||||
@@ -75,8 +76,26 @@ void asst::SanityBeforeStagePlugin::get_sanity()
|
||||
sanity_info["details"]["sanity"] = text;
|
||||
callback(AsstMsg::SubTaskExtraInfo, sanity_info);
|
||||
|
||||
json::array value;
|
||||
value.emplace_back(std::move(text));
|
||||
value.emplace_back(utils::get_format_time());
|
||||
status()->set_str(Status::FightSanityReport, value.dumps());
|
||||
std::string sanity_report_str = std::string();
|
||||
do {
|
||||
auto slash_pos = text.find('/');
|
||||
if (slash_pos == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
if (ranges::any_of(text, [](const char& c) { return c != '/' && !isdigit(c); })) {
|
||||
break;
|
||||
}
|
||||
|
||||
int sanity_cur = 0, sanity_max = 0;
|
||||
if (std::from_chars(text.data(), text.data() + slash_pos, sanity_cur).ec != std::errc()) {
|
||||
break;
|
||||
}
|
||||
if (std::from_chars(text.data() + slash_pos + 1, text.data() + text.length(), sanity_max).ec != std::errc()) {
|
||||
break;
|
||||
}
|
||||
sanity_report_str = json::object {
|
||||
{ "current_sanity", sanity_cur }, { "max_sanity", sanity_cur }, { "report_time", utils::get_format_time() }
|
||||
}.dumps();
|
||||
} while (false);
|
||||
status()->set_str(Status::FightSanityReport, sanity_report_str);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,6 @@ namespace asst
|
||||
private:
|
||||
virtual bool _run() override;
|
||||
|
||||
void get_sanity();
|
||||
void get_sanity_before_stage();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -205,15 +205,21 @@ bool asst::BattleFormationTask::add_trust_operators()
|
||||
}
|
||||
else {
|
||||
failed_count = 0;
|
||||
for (const auto& trust_icon : matcher.get_result()) {
|
||||
std::vector<MatchRect> result = matcher.get_result();
|
||||
// 按先上下后左右排个序
|
||||
sort_by_vertical_(result);
|
||||
for (const auto& trust_icon : result) {
|
||||
// 匹配完干员左下角信赖表,将roi偏移到整个干员标
|
||||
ctrler()->click(trust_icon.rect.move({ 20, -225, 110, 250 }));
|
||||
if (--append_count <= 0 || need_exit()) {
|
||||
--append_count;
|
||||
if (append_count <= 0 || need_exit()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
swipe_page();
|
||||
if (!need_exit() && append_count > 0) {
|
||||
swipe_page();
|
||||
}
|
||||
}
|
||||
|
||||
return append_count == 0;
|
||||
|
||||
@@ -93,6 +93,10 @@ bool ProcessTask::_run()
|
||||
if (need_exit()) {
|
||||
return false;
|
||||
}
|
||||
if (!m_enable) {
|
||||
Log.info("task disabled, pass", basic_info().to_string());
|
||||
return true;
|
||||
}
|
||||
if (m_cur_task_ptr && m_pre_task_name != m_cur_task_ptr->name) {
|
||||
m_pre_task_name = m_cur_task_ptr->name;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ namespace MaaWpfGui.Helper
|
||||
/// </summary>
|
||||
/// <param name="key">The configuration key.</param>
|
||||
/// <returns>The return value of <see cref="Save"/>.</returns>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public static bool DeleteValue(string key)
|
||||
{
|
||||
lock (_lock)
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace MaaWpfGui.Helper
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool GetConfiguration(out WindowPlacement wp)
|
||||
private static bool GetConfiguration(out WindowPlacement wp)
|
||||
{
|
||||
wp = default;
|
||||
var jsonStr = ConfigurationHelper.GetValue(ConfigurationKeys.WindowPlacement, string.Empty);
|
||||
|
||||
@@ -41,6 +41,18 @@
|
||||
<ItemGroup>
|
||||
<AdditionalFiles Include="stylecop.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<COMReference Include="IWshRuntimeLibrary">
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<Guid>f935dc20-1cf0-11d0-adb9-00c04fd58a0b</Guid>
|
||||
<Lcid>0</Lcid>
|
||||
<Isolated>false</Isolated>
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<!-- StyleCop -->
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -589,8 +589,8 @@ namespace MaaWpfGui.Main
|
||||
case AsstMsg.AllTasksCompleted:
|
||||
bool isMainTaskQueueAllCompleted = true;
|
||||
var finished_tasks = details["finished_tasks"] as JArray;
|
||||
var sanity_report = details["sanity"] as JArray;
|
||||
if (finished_tasks.Count == 1)
|
||||
var sanity_report = details["sanity_report"] as JObject;
|
||||
if (finished_tasks?.Count == 1)
|
||||
{
|
||||
var unique_finished_task = (AsstTaskId)finished_tasks[0];
|
||||
if (unique_finished_task == (_latestTaskId.TryGetValue(TaskType.Copilot, out var copilotTaskId) ? copilotTaskId : 0)
|
||||
@@ -604,12 +604,7 @@ namespace MaaWpfGui.Main
|
||||
}
|
||||
}
|
||||
|
||||
bool buy_wine = false;
|
||||
if (_latestTaskId.ContainsKey(TaskType.Mall) && Instances.SettingsViewModel.DidYouBuyWine())
|
||||
{
|
||||
buy_wine = true;
|
||||
}
|
||||
|
||||
bool buy_wine = _latestTaskId.ContainsKey(TaskType.Mall) && Instances.SettingsViewModel.DidYouBuyWine();
|
||||
_latestTaskId.Clear();
|
||||
|
||||
Instances.TaskQueueViewModel.ResetFightVariables();
|
||||
@@ -618,19 +613,25 @@ namespace MaaWpfGui.Main
|
||||
|
||||
if (isMainTaskQueueAllCompleted)
|
||||
{
|
||||
bool isSanityForecastSucc = true;
|
||||
DateTimeOffset? reportTime = null;
|
||||
bool isSanityForecastSucc = false;
|
||||
DateTimeOffset reportTime = default;
|
||||
TimeSpan timeDiff = TimeSpan.Zero;
|
||||
if (isSanityForecastSucc &= sanity_report != null && sanity_report.Count == 2 && ((string)sanity_report[0]).Contains("/"))
|
||||
try
|
||||
{
|
||||
int[] sanity = ((string)sanity_report[0]).Split('/').Select(i => Convert.ToInt32(i)).ToArray();
|
||||
reportTime = DateTimeOffset.Parse((string)sanity_report[1]);
|
||||
if (isSanityForecastSucc &= sanity.Length == 2 && sanity[1] > 1)
|
||||
int current_sanity = (int)sanity_report["current_sanity"];
|
||||
int max_sanity = (int)sanity_report["max_sanity"];
|
||||
string report_time = sanity_report["report_time"].ToString();
|
||||
if (current_sanity >= 0 && max_sanity > 1)
|
||||
{
|
||||
timeDiff = new TimeSpan(0, sanity[0] < sanity[1] ? (sanity[1] - sanity[0]) * 6 : 0, 0);
|
||||
reportTime = reportTime?.AddMinutes(timeDiff.TotalMinutes);
|
||||
timeDiff = new TimeSpan(0, current_sanity < max_sanity ? (max_sanity - current_sanity) * 6 : 0, 0);
|
||||
reportTime = DateTimeOffset.Parse(report_time).AddMinutes(timeDiff.TotalMinutes);
|
||||
isSanityForecastSucc = true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.Information($"Failed to parse sanity report {sanity_report}");
|
||||
}
|
||||
|
||||
var allTaskCompleteTitle = LocalizationHelper.GetString("AllTasksComplete");
|
||||
var allTaskCompleteMessage = LocalizationHelper.GetString("AllTaskCompleteContent");
|
||||
@@ -643,7 +644,7 @@ namespace MaaWpfGui.Main
|
||||
.Replace("{Preset}", configurationPreset);
|
||||
if (isSanityForecastSucc)
|
||||
{
|
||||
sanityReport = sanityReport.Replace("{DateTime}", reportTime?.ToString("T")).Replace("{TimeDiff}", timeDiff.ToString(@"hh\:mm"));
|
||||
sanityReport = sanityReport.Replace("{DateTime}", reportTime.ToString("yyyy-MM-dd HH:mm")).Replace("{TimeDiff}", timeDiff.ToString(@"h\h\ m\m"));
|
||||
|
||||
Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("AllTasksComplete") + Environment.NewLine + sanityReport);
|
||||
ExternalNotificationService.Send(allTaskCompleteTitle, allTaskCompleteMessage + Environment.NewLine + sanityReport);
|
||||
@@ -1228,7 +1229,7 @@ namespace MaaWpfGui.Main
|
||||
/// </summary>
|
||||
/// <param name="address">连接地址。</param>
|
||||
/// <returns>是否有效。</returns>
|
||||
public bool IfPortEstablished(string address)
|
||||
private static bool IfPortEstablished(string address)
|
||||
{
|
||||
if (string.IsNullOrEmpty(address) || !address.Contains(":"))
|
||||
{
|
||||
@@ -1245,28 +1246,24 @@ namespace MaaWpfGui.Main
|
||||
string host = address_[0].Equals("emulator") ? "127.0.0.1" : address_[0];
|
||||
int port = int.Parse(address_[1]);
|
||||
|
||||
using (var client = new TcpClient())
|
||||
using var client = new TcpClient();
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
IAsyncResult result = client.BeginConnect(host, port, null, null);
|
||||
bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(.5));
|
||||
IAsyncResult result = client.BeginConnect(host, port, null, null);
|
||||
bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(.5));
|
||||
|
||||
if (success)
|
||||
{
|
||||
client.EndConnect(result);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
client.Close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
if (success)
|
||||
{
|
||||
return false;
|
||||
client.EndConnect(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
client.Close();
|
||||
return false;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1905,23 +1902,16 @@ namespace MaaWpfGui.Main
|
||||
};
|
||||
AsstTaskId id = AsstAppendTaskWithEncoding(type, task_params);
|
||||
_latestTaskId[TaskType.Copilot] = id;
|
||||
if (asst_start)
|
||||
{
|
||||
return id != 0 && AsstStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
return id != 0;
|
||||
}
|
||||
return id != 0 && (!asst_start || AsstStart());
|
||||
}
|
||||
|
||||
public bool AsstStartVideoRec(string filename)
|
||||
{
|
||||
var task_params = new JObject
|
||||
var taskParams = new JObject
|
||||
{
|
||||
["filename"] = filename,
|
||||
};
|
||||
AsstTaskId id = AsstAppendTaskWithEncoding("VideoRecognition", task_params);
|
||||
AsstTaskId id = AsstAppendTaskWithEncoding("VideoRecognition", taskParams);
|
||||
_latestTaskId[TaskType.Copilot] = id;
|
||||
return id != 0 && AsstStart();
|
||||
}
|
||||
|
||||
@@ -227,25 +227,6 @@ namespace MaaWpfGui.Main
|
||||
base.OnExit(e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 会带参数重启,切换配置等操作会切换回去
|
||||
/// </summary>
|
||||
public static void RestartApplication()
|
||||
{
|
||||
//// 释放互斥量
|
||||
/*
|
||||
_mutex?.ReleaseMutex();
|
||||
_mutex?.Dispose();
|
||||
|
||||
// 避免 OnExit 时再次释放
|
||||
_mutex = null;
|
||||
*/
|
||||
|
||||
// 有时候软件自重启时 gui.log 会无法正常写入
|
||||
Log.CloseAndFlush();
|
||||
System.Windows.Forms.Application.Restart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启,不带参数
|
||||
/// </summary>
|
||||
|
||||
@@ -9,11 +9,11 @@ using Stylet;
|
||||
|
||||
namespace MaaWpfGui.Models
|
||||
{
|
||||
public class ResourceUpdater
|
||||
public static class ResourceUpdater
|
||||
{
|
||||
private const string MaaResourceApi = "https://ota.maa.plus/MaaAssistantArknights/MaaAssistantArknights/";
|
||||
|
||||
private static readonly List<string> MaaSingleFiles = new List<string>
|
||||
private static readonly List<string> _maaSingleFiles = new List<string>
|
||||
{
|
||||
"resource/Arknights-Tile-Pos/overview.json",
|
||||
"resource/battle_data.json",
|
||||
@@ -36,7 +36,7 @@ namespace MaaWpfGui.Models
|
||||
"resource/global/YoStarKR/resource/version.json",
|
||||
};
|
||||
|
||||
private static readonly string MaaDynamicFilesIndex = "resource/dynamic_list.txt";
|
||||
private const string MaaDynamicFilesIndex = "resource/dynamic_list.txt";
|
||||
|
||||
public enum UpdateResult
|
||||
{
|
||||
@@ -63,15 +63,16 @@ namespace MaaWpfGui.Models
|
||||
{
|
||||
_updating = false;
|
||||
|
||||
var ret1 = await updateSingleFiles();
|
||||
var ret2 = await updateFilesWithIndex();
|
||||
var ret1 = await UpdateSingleFiles();
|
||||
var ret2 = await UpdateFilesWithIndex();
|
||||
ETagCache.Save();
|
||||
|
||||
if (ret1 == UpdateResult.Failed || ret2 == UpdateResult.Failed)
|
||||
{
|
||||
return UpdateResult.Failed;
|
||||
}
|
||||
else if (ret1 == UpdateResult.Success || ret2 == UpdateResult.Success)
|
||||
|
||||
if (ret1 == UpdateResult.Success || ret2 == UpdateResult.Success)
|
||||
{
|
||||
return UpdateResult.Success;
|
||||
}
|
||||
@@ -79,11 +80,11 @@ namespace MaaWpfGui.Models
|
||||
return UpdateResult.NotModified;
|
||||
}
|
||||
|
||||
private static async Task<UpdateResult> updateSingleFiles()
|
||||
private static async Task<UpdateResult> UpdateSingleFiles()
|
||||
{
|
||||
UpdateResult ret = UpdateResult.NotModified;
|
||||
|
||||
foreach (var file in MaaSingleFiles)
|
||||
foreach (var file in _maaSingleFiles)
|
||||
{
|
||||
var sRet = await UpdateFileWithETag(MaaResourceApi, file, file);
|
||||
|
||||
@@ -103,7 +104,7 @@ namespace MaaWpfGui.Models
|
||||
|
||||
// 地图文件、掉落材料的图片、基建技能图片
|
||||
// 这些文件数量不固定,需要先获取索引文件,再根据索引文件下载
|
||||
private static async Task<UpdateResult> updateFilesWithIndex()
|
||||
private static async Task<UpdateResult> UpdateFilesWithIndex()
|
||||
{
|
||||
var indexSRet = await UpdateFileWithETag(MaaResourceApi, MaaDynamicFilesIndex, MaaDynamicFilesIndex);
|
||||
if (indexSRet == UpdateResult.Failed || indexSRet == UpdateResult.NotModified)
|
||||
@@ -114,7 +115,12 @@ namespace MaaWpfGui.Models
|
||||
var ret = UpdateResult.NotModified;
|
||||
var context = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, MaaDynamicFilesIndex));
|
||||
|
||||
context.Split('\n').ToList().ForEach(async file =>
|
||||
context.Split('\n').ToList().ForEach(Action);
|
||||
|
||||
return ret;
|
||||
|
||||
// lambda 避免使用异步,任何未被 lambda 处理的异常都可能导致进程崩溃
|
||||
async void Action(string file)
|
||||
{
|
||||
if (string.IsNullOrEmpty(file))
|
||||
{
|
||||
@@ -138,14 +144,12 @@ namespace MaaWpfGui.Models
|
||||
{
|
||||
ret = UpdateResult.Success;
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _updating;
|
||||
|
||||
public static async Task<UpdateResult> UpdateFileWithETag(string baseUrl, string file, string saveTo)
|
||||
private static async Task<UpdateResult> UpdateFileWithETag(string baseUrl, string file, string saveTo)
|
||||
{
|
||||
saveTo = Path.Combine(Environment.CurrentDirectory, saveTo);
|
||||
var url = baseUrl + file;
|
||||
|
||||
@@ -544,7 +544,7 @@ The video aspect ratio needs to be 16:9 without interference factors such as bla
|
||||
<system:String x:Key="StartCombat" xml:space="preserve">Start combat: </system:String>
|
||||
<system:String x:Key="CompleteCombat">Complete combat</system:String>
|
||||
<system:String x:Key="AllTasksComplete">All task(s) completed!</system:String>
|
||||
<system:String x:Key="SanityReport">Sanity will be full on {DateTime} ({TimeDiff} later).</system:String>
|
||||
<system:String x:Key="SanityReport">Sanity will be full at {DateTime}.({TimeDiff} later)</system:String>
|
||||
<system:String x:Key="AllTaskCompleteContent">MAA has completed all tasks under the {Preset} configuration in {DateTime}.</system:String>
|
||||
<system:String x:Key="BackgroundLinkStarted">Tasks started</system:String>
|
||||
<system:String x:Key="BackgroundLinkStopped">Tasks stopped</system:String>
|
||||
|
||||
@@ -544,7 +544,7 @@ Bilibili: ログイン インターフェイスに表示されるアカウント
|
||||
<system:String x:Key="StartCombat" xml:space="preserve">戦闘開始: </system:String>
|
||||
<system:String x:Key="CompleteCombat">戦闘完了</system:String>
|
||||
<system:String x:Key="AllTasksComplete">すべてのタスクが完了しました!</system:String>
|
||||
<system:String x:Key="SanityReport">理性は {DateTime} に満杯になります ({TimeDiff} 後)。</system:String>
|
||||
<system:String x:Key="SanityReport">理性は {DateTime} に満杯になります。({TimeDiff} 後)</system:String>
|
||||
<system:String x:Key="AllTaskCompleteContent">MAA は、{DateTime} の {Preset} 構成の下にあるすべてのプリセット タスクを完了しました。</system:String>
|
||||
<system:String x:Key="BackgroundLinkStarted">Tasks started</system:String>
|
||||
<system:String x:Key="BackgroundLinkStopped">Tasks stopped</system:String>
|
||||
|
||||
@@ -544,7 +544,7 @@ Bilibili: 로그인 인터페이스에 표시되는 계정 이름(예: Zhang San
|
||||
<system:String x:Key="StartCombat" xml:space="preserve">작전 시작: </system:String>
|
||||
<system:String x:Key="CompleteCombat">작전 완료</system:String>
|
||||
<system:String x:Key="AllTasksComplete">모든 작업이 완료되었습니다!</system:String>
|
||||
<system:String x:Key="SanityReport">{DateTime}({TimeDiff} 이후)에 정신 상태가 가득 차게 됩니다.</system:String>
|
||||
<system:String x:Key="SanityReport">{DateTime}에 정신 상태가 가득 차게 됩니다.({TimeDiff} 이후)</system:String>
|
||||
<system:String x:Key="AllTaskCompleteContent">MAA는 {DateTime}의 {Preset} 구성에서 모든 사전 설정 작업을 완료했습니다.</system:String>
|
||||
<system:String x:Key="BackgroundLinkStarted">작업 시작됨</system:String>
|
||||
<system:String x:Key="BackgroundLinkStopped">작업 중지됨</system:String>
|
||||
|
||||
@@ -544,7 +544,7 @@
|
||||
<system:String x:Key="StartCombat" xml:space="preserve">开始战斗: </system:String>
|
||||
<system:String x:Key="CompleteCombat">完成战斗</system:String>
|
||||
<system:String x:Key="AllTasksComplete">任务已全部完成!</system:String>
|
||||
<system:String x:Key="SanityReport">理智将在 {DateTime} ({TimeDiff} 后) 回满。</system:String>
|
||||
<system:String x:Key="SanityReport">理智将在 {DateTime} 回满。({TimeDiff} 后)</system:String>
|
||||
<system:String x:Key="AllTaskCompleteContent">MAA 已在 {DateTime} 完成了 {Preset} 配置下所有预设的任务。</system:String>
|
||||
<system:String x:Key="BackgroundLinkStarted">开始执行任务</system:String>
|
||||
<system:String x:Key="BackgroundLinkStopped">任务终止</system:String>
|
||||
|
||||
@@ -544,7 +544,7 @@
|
||||
<system:String x:Key="StartCombat" xml:space="preserve">開始戰鬥: </system:String>
|
||||
<system:String x:Key="CompleteCombat">完成戰鬥</system:String>
|
||||
<system:String x:Key="AllTasksComplete">任務已全部完成!</system:String>
|
||||
<system:String x:Key="SanityReport">理智會在 {DateTime} ({TimeDiff} 後) 回滿。</system:String>
|
||||
<system:String x:Key="SanityReport">理智會在 {DateTime}回滿。({TimeDiff} 後)</system:String>
|
||||
<system:String x:Key="AllTaskCompleteContent">MAA 已在 {DateTime} 完成了 {Preset} 配置下所有預設的任務。</system:String>
|
||||
<system:String x:Key="BackgroundLinkStarted">開始執行任務</system:String>
|
||||
<system:String x:Key="BackgroundLinkStopped">任務終止</system:String>
|
||||
|
||||
@@ -68,10 +68,13 @@ namespace MaaWpfGui.Services.Notification
|
||||
|
||||
private class ServerChanPostContent
|
||||
{
|
||||
// 这两个没用过,不知道有没有用,之后再看看
|
||||
[JsonPropertyName("title")]
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonPropertyName("desp")]
|
||||
// ReSharper disable once UnusedAutoPropertyAccessor.Local
|
||||
public string Content { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace MaaWpfGui.Services.Web
|
||||
{
|
||||
var response = await GetAsync(uri, extraHeader);
|
||||
|
||||
if (response == null || response.StatusCode != HttpStatusCode.OK)
|
||||
if (response?.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace MaaWpfGui.Services.Web
|
||||
{
|
||||
var response = await GetAsync(uri, extraHeader);
|
||||
|
||||
if (response == null || response.StatusCode != HttpStatusCode.OK)
|
||||
if (response?.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ namespace MaaWpfGui.Services.Web
|
||||
|
||||
var response = await GetAsync(uri, extraHeader: new Dictionary<string, string> { { "Accept", contentType } }, httpCompletionOption: HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
if (response == null || response.StatusCode != HttpStatusCode.OK)
|
||||
if (response?.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -264,7 +264,6 @@ namespace MaaWpfGui.Services.Web
|
||||
}
|
||||
|
||||
HttpClient client = new HttpClient(handler);
|
||||
client = new HttpClient(handler);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", UserAgent);
|
||||
client.Timeout = TimeSpan.FromSeconds(15);
|
||||
return client;
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
// but WITHOUT ANY WARRANTY
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Win32;
|
||||
using System.IO;
|
||||
|
||||
namespace MaaWpfGui.Utilities
|
||||
{
|
||||
@@ -21,7 +22,17 @@ namespace MaaWpfGui.Utilities
|
||||
/// </summary>
|
||||
public static class AutoStart
|
||||
{
|
||||
private static readonly string fileValue = Process.GetCurrentProcess().MainModule?.FileName;
|
||||
private static readonly string _fileValue = Process.GetCurrentProcess().MainModule?.FileName;
|
||||
private static readonly string _uniqueIdentifier = GetUniqueIdentifierFromPath(_fileValue);
|
||||
|
||||
private static readonly string _startupFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
|
||||
private static readonly string _startupShortcutPath = Path.Combine(_startupFolderPath, $"MAA_{_uniqueIdentifier}.lnk");
|
||||
|
||||
static string GetUniqueIdentifierFromPath(string path)
|
||||
{
|
||||
int hash = path.GetHashCode();
|
||||
return hash.ToString("X");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether this program starts up with OS.
|
||||
@@ -31,8 +42,7 @@ namespace MaaWpfGui.Utilities
|
||||
{
|
||||
try
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", false);
|
||||
return key.GetValue("MeoAsst") != null;
|
||||
return File.Exists(_startupShortcutPath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -49,14 +59,22 @@ namespace MaaWpfGui.Utilities
|
||||
{
|
||||
try
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
|
||||
if (set)
|
||||
{
|
||||
key.SetValue("MeoAsst", "\"" + fileValue + "\"");
|
||||
// 创建启动文件夹的快捷方式
|
||||
var shell = new IWshRuntimeLibrary.WshShell();
|
||||
var shortcut = shell.CreateShortcut(_startupShortcutPath);
|
||||
shortcut.TargetPath = _fileValue;
|
||||
shortcut.WorkingDirectory = Path.GetDirectoryName(_fileValue);
|
||||
shortcut.Save();
|
||||
}
|
||||
else
|
||||
{
|
||||
key.DeleteValue("MeoAsst");
|
||||
// 删除启动文件夹的快捷方式
|
||||
if (File.Exists(_startupShortcutPath))
|
||||
{
|
||||
File.Delete(_startupShortcutPath);
|
||||
}
|
||||
}
|
||||
|
||||
return set == CheckStart();
|
||||
|
||||
@@ -13,32 +13,20 @@ namespace MaaWpfGui.ViewModels
|
||||
/// <param name="isChecked">isChecked</param>
|
||||
public CopilotItemViewModel(string name, string filePath, bool isChecked = true)
|
||||
{
|
||||
_name = name;
|
||||
_filePath = filePath;
|
||||
Name = name;
|
||||
FilePath = filePath;
|
||||
_isChecked = isChecked;
|
||||
}
|
||||
|
||||
private string _filePath;
|
||||
/// <summary>
|
||||
/// Gets the original_name.
|
||||
/// </summary>
|
||||
public string FilePath { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the original_name.
|
||||
/// Gets the name.
|
||||
/// </summary>
|
||||
public string FilePath
|
||||
{
|
||||
get => _filePath;
|
||||
set => SetAndNotify(ref _filePath, value);
|
||||
}
|
||||
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetAndNotify(ref _name, value);
|
||||
}
|
||||
public string Name { get; }
|
||||
|
||||
private bool _isChecked;
|
||||
|
||||
@@ -55,51 +43,12 @@ namespace MaaWpfGui.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
// 换成图标的话要这个,暂时没用
|
||||
private string _iconPath;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon path.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string IconPath
|
||||
{
|
||||
get => _iconPath;
|
||||
set => SetAndNotify(ref _iconPath, value);
|
||||
}
|
||||
|
||||
private string _token;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the token.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string Token
|
||||
{
|
||||
get => _token;
|
||||
set => SetAndNotify(ref _token, value);
|
||||
}
|
||||
|
||||
private string _runStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the running status.
|
||||
/// </summary>
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public string RunStatus
|
||||
{
|
||||
get => _runStatus;
|
||||
set => SetAndNotify(ref _runStatus, value);
|
||||
}
|
||||
|
||||
private int _index = 0;
|
||||
private int _index;
|
||||
|
||||
public int Index
|
||||
{
|
||||
get => _index;
|
||||
set => SetAndNotify(ref _index, value);
|
||||
}
|
||||
|
||||
public int GetIndex() => Index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,19 +66,21 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
_runningState.IdleChanged += RunningState_IdleChanged;
|
||||
|
||||
var copilotTaskList = ConfigurationHelper.GetValue(ConfigurationKeys.CopilotTaskList, string.Empty);
|
||||
if (!string.IsNullOrEmpty(copilotTaskList))
|
||||
if (string.IsNullOrEmpty(copilotTaskList))
|
||||
{
|
||||
JArray jArray = JArray.Parse(copilotTaskList);
|
||||
foreach (var item in jArray)
|
||||
{
|
||||
if ((item as JObject).TryGetValue("file_path", out var token) && File.Exists(token.ToString()))
|
||||
{
|
||||
CopilotItemViewModels.Add(new CopilotItemViewModel((string)item["name"], (string)item["file_path"], (bool)item["is_checked"]));
|
||||
}
|
||||
}
|
||||
|
||||
CopilotItemIndexChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
JArray jArray = JArray.Parse(copilotTaskList);
|
||||
foreach (var item in jArray)
|
||||
{
|
||||
if (((JObject)item).TryGetValue("file_path", out var token) && File.Exists(token.ToString()))
|
||||
{
|
||||
CopilotItemViewModels.Add(new CopilotItemViewModel((string)item["name"], (string)item["file_path"], (bool)item["is_checked"]));
|
||||
}
|
||||
}
|
||||
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
|
||||
private void RunningState_IdleChanged(object sender, bool e)
|
||||
@@ -570,32 +572,36 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
|
||||
private const string CopilotJsonDir = "cache/copilot";
|
||||
|
||||
//UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void AddCopilotTask()
|
||||
{
|
||||
var stage_name = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stage_name.IsNullOrEmpty())
|
||||
var stageName = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stageName.IsNullOrEmpty())
|
||||
{
|
||||
AddCopilotTaskToList(stage_name);
|
||||
AddCopilotTaskToList(stageName);
|
||||
}
|
||||
}
|
||||
|
||||
//UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void AddCopilotTask_Adverse()
|
||||
{
|
||||
var stage_name = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stage_name.EndsWith("-Adverse"))
|
||||
var stageName = CopilotTaskName.Trim().Replace("突袭", "-Adverse");
|
||||
if (!stageName.EndsWith("-Adverse"))
|
||||
{
|
||||
stage_name += "-Adverse";
|
||||
stageName += "-Adverse";
|
||||
}
|
||||
|
||||
if (!stage_name.IsNullOrEmpty())
|
||||
if (!stageName.IsNullOrEmpty())
|
||||
{
|
||||
AddCopilotTaskToList(stage_name);
|
||||
AddCopilotTaskToList(stageName);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddCopilotTaskToList(string stage_name)
|
||||
private void AddCopilotTaskToList(string stageName)
|
||||
{
|
||||
var jsonPath = $"{CopilotJsonDir}/{stage_name}.json";
|
||||
var jsonPath = $"{CopilotJsonDir}/{stageName}.json";
|
||||
|
||||
try
|
||||
{
|
||||
@@ -603,12 +609,18 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Copy(IsDataFromWeb ? TempCopilotFile : Filename, jsonPath, true);
|
||||
var item = new CopilotItemViewModel(stage_name, jsonPath)
|
||||
if (jsonPath != (IsDataFromWeb ? TempCopilotFile : Filename))
|
||||
{
|
||||
// 相同路径跳拷贝
|
||||
File.Copy(IsDataFromWeb ? TempCopilotFile : Filename, jsonPath, true);
|
||||
}
|
||||
|
||||
var item = new CopilotItemViewModel(stageName, jsonPath)
|
||||
{
|
||||
Index = CopilotItemViewModels.Count,
|
||||
};
|
||||
@@ -633,12 +645,16 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
ConfigurationHelper.SetValue(ConfigurationKeys.CopilotTaskList, JsonConvert.SerializeObject(jArray));
|
||||
}
|
||||
|
||||
//UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void DeleteCopilotTask(int index)
|
||||
{
|
||||
CopilotItemViewModels.RemoveAt(index);
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
|
||||
//UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void CleanUnableCopilotTask()
|
||||
{
|
||||
foreach (var item in CopilotItemViewModels.Where(model => !model.IsChecked).ToList())
|
||||
@@ -649,6 +665,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
CopilotItemIndexChanged();
|
||||
}
|
||||
|
||||
//UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void ClearCopilotTask()
|
||||
{
|
||||
CopilotItemViewModels.Clear();
|
||||
@@ -659,13 +677,15 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
for (int i = 0; i < CopilotItemViewModels.Count; i++)
|
||||
foreach (var model in CopilotItemViewModels)
|
||||
{
|
||||
if (CopilotItemViewModels[i].IsChecked)
|
||||
if (!model.IsChecked)
|
||||
{
|
||||
CopilotItemViewModels[i].IsChecked = false;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
model.IsChecked = false;
|
||||
break;
|
||||
}
|
||||
|
||||
SaveCopilotTask();
|
||||
@@ -675,7 +695,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
/// <summary>
|
||||
/// 更新任务顺序
|
||||
/// </summary>
|
||||
public void CopilotItemIndexChanged()
|
||||
private void CopilotItemIndexChanged()
|
||||
{
|
||||
Application.Current.Dispatcher.InvokeAsync(() =>
|
||||
{
|
||||
|
||||
@@ -152,6 +152,8 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
|
||||
#region External Notifications
|
||||
|
||||
// UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void ExternalNotificationSendTest()
|
||||
{
|
||||
ExternalNotificationService.Send(
|
||||
@@ -160,7 +162,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
true);
|
||||
}
|
||||
|
||||
public List<CombinedData> ExternalNotificationProviders => new List<CombinedData>
|
||||
public static List<CombinedData> ExternalNotificationProviders => new List<CombinedData>
|
||||
{
|
||||
new CombinedData { Display = LocalizationHelper.GetString("Off"), Value = "Off" },
|
||||
new CombinedData { Display = "Server Chan", Value = "ServerChan" },
|
||||
@@ -560,7 +562,9 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
}
|
||||
|
||||
public void AccountSwitchMannualRun()
|
||||
// UI 绑定的方法
|
||||
// ReSharper disable once UnusedMember.Global
|
||||
public void AccountSwitchManualRun()
|
||||
{
|
||||
Instances.TaskQueueViewModel.QuickSwitchAccount();
|
||||
}
|
||||
@@ -968,33 +972,34 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
// This allows for SQL injection, but since it is not on a real database nothing horrible would happen.
|
||||
// The following query string does what I want, but WMI does not accept it.
|
||||
// var wmiQueryString = string.Format("SELECT ProcessId, CommandLine FROM Win32_Process WHERE ExecutablePath='{0}'", adbPath);
|
||||
var wmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
|
||||
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
|
||||
using (var results = searcher.Get())
|
||||
{
|
||||
var query = from p in Process.GetProcesses()
|
||||
join mo in results.Cast<ManagementObject>()
|
||||
const string WmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
|
||||
using var searcher = new ManagementObjectSearcher(WmiQueryString);
|
||||
using var results = searcher.Get();
|
||||
var query = from p in Process.GetProcesses()
|
||||
join mo in results.Cast<ManagementObject>()
|
||||
on p.Id equals (int)(uint)mo["ProcessId"]
|
||||
select new
|
||||
{
|
||||
Process = p,
|
||||
Path = (string)mo["ExecutablePath"],
|
||||
};
|
||||
foreach (var item in query)
|
||||
select new
|
||||
{
|
||||
Process = p,
|
||||
Path = (string)mo["ExecutablePath"],
|
||||
};
|
||||
foreach (var item in query)
|
||||
{
|
||||
if (item.Path != adbPath)
|
||||
{
|
||||
if (item.Path == adbPath)
|
||||
{
|
||||
// Some emulators start their adb with administrator privilege.
|
||||
// Not sure if this is necessary
|
||||
try
|
||||
{
|
||||
item.Process.Kill();
|
||||
item.Process.WaitForExit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Some emulators start their adb with administrator privilege.
|
||||
// Not sure if this is necessary
|
||||
try
|
||||
{
|
||||
item.Process.Kill();
|
||||
item.Process.WaitForExit();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1598,7 +1603,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeMode, value);
|
||||
|
||||
// 烧开水模式可选项
|
||||
this.RoguelikeStartWithEliteTwoEnable = mapRoguelikeStartWithEliteTwoEnable(value);
|
||||
this.RoguelikeStartWithEliteTwoEnable = MapRoguelikeStartWithEliteTwoEnable(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1661,7 +1666,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
public ObservableCollection<string> RoguelikeCoreCharList
|
||||
{
|
||||
get => _roguelikeCoreCharList;
|
||||
set => SetAndNotify(ref _roguelikeCoreCharList, value);
|
||||
private set => SetAndNotify(ref _roguelikeCoreCharList, value);
|
||||
}
|
||||
|
||||
private string _roguelikeStartWithEliteTwo = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeStartWithEliteTwo, false.ToString());
|
||||
@@ -1674,7 +1679,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
get => bool.Parse(_roguelikeStartWithEliteTwo);
|
||||
set
|
||||
{
|
||||
if (value == true && RoguelikeUseSupportUnit == true)
|
||||
if (value && RoguelikeUseSupportUnit)
|
||||
{
|
||||
RoguelikeUseSupportUnit = false;
|
||||
}
|
||||
@@ -1684,7 +1689,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
}
|
||||
|
||||
private string _roguelikeStartWithEliteTwoEnable = mapRoguelikeStartWithEliteTwoEnable(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeMode, "0"));
|
||||
private string _roguelikeStartWithEliteTwoEnable = MapRoguelikeStartWithEliteTwoEnable(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeMode, "0"));
|
||||
|
||||
public string RoguelikeStartWithEliteTwoEnable
|
||||
{
|
||||
@@ -1699,14 +1704,9 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
}
|
||||
}
|
||||
|
||||
private static string mapRoguelikeStartWithEliteTwoEnable(string mode)
|
||||
private static string MapRoguelikeStartWithEliteTwoEnable(string mode)
|
||||
{
|
||||
if (mode == "4")
|
||||
{
|
||||
return "Visible";
|
||||
}
|
||||
|
||||
return "Collapsed";
|
||||
return mode == "4" ? "Visible" : "Collapsed";
|
||||
}
|
||||
|
||||
private string _roguelikeUseSupportUnit = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeUseSupportUnit, false.ToString());
|
||||
@@ -1719,7 +1719,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
get => bool.Parse(_roguelikeUseSupportUnit);
|
||||
set
|
||||
{
|
||||
if (value == true && RoguelikeStartWithEliteTwo == true)
|
||||
if (value && RoguelikeStartWithEliteTwo)
|
||||
{
|
||||
RoguelikeStartWithEliteTwo = false;
|
||||
}
|
||||
@@ -2720,9 +2720,9 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
/// <summary>
|
||||
/// RegisterKey of Bluestacks_Nxt
|
||||
/// </summary>
|
||||
public static string BluestacksNxtRegistryKey = @"SOFTWARE\BlueStacks_nxt";
|
||||
private const string BluestacksNxtRegistryKey = @"SOFTWARE\BlueStacks_nxt";
|
||||
|
||||
public static string BluestacksNxtValueName = "UserDefinedDir";
|
||||
private const string BluestacksNxtValueName = "UserDefinedDir";
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes ADB config.
|
||||
@@ -2795,7 +2795,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
/// Get the path of bluestacks.conf
|
||||
/// </summary>
|
||||
/// <returns>path</returns>
|
||||
public static string GetBluestacksConfig()
|
||||
private static string GetBluestacksConfig()
|
||||
{
|
||||
var conf = ConfigurationHelper.GetValue(ConfigurationKeys.BluestacksConfigPath, string.Empty);
|
||||
if (!string.IsNullOrEmpty(conf))
|
||||
@@ -2803,16 +2803,11 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
return conf;
|
||||
}
|
||||
|
||||
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(BluestacksNxtRegistryKey))
|
||||
using RegistryKey key = Registry.LocalMachine.OpenSubKey(BluestacksNxtRegistryKey);
|
||||
object value = key?.GetValue(BluestacksNxtValueName);
|
||||
if (value != null)
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
object value = key.GetValue(BluestacksNxtValueName);
|
||||
if (value != null)
|
||||
{
|
||||
return (string)value + "\\bluestacks.conf";
|
||||
}
|
||||
}
|
||||
return (string)value + "\\bluestacks.conf";
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -3576,19 +3571,11 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
return true;
|
||||
}
|
||||
|
||||
var wine_list = new[] { "酒", "drink", "wine", "beer", "술", "🍷", "🍸", "🍺", "🍻", "🥃", "🍶" };
|
||||
foreach (var wine in wine_list)
|
||||
{
|
||||
if (CreditFirstList.Contains(wine))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
var wineList = new[] { "酒", "drink", "wine", "beer", "술", "🍷", "🍸", "🍺", "🍻", "🥃", "🍶" };
|
||||
return wineList.Any(wine => CreditFirstList.Contains(wine));
|
||||
}
|
||||
|
||||
public void UpdateRoguelikeSquadList()
|
||||
private void UpdateRoguelikeSquadList()
|
||||
{
|
||||
var roguelikeSquad = RoguelikeSquad;
|
||||
|
||||
@@ -3665,7 +3652,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
_roguelikeSquad = RoguelikeSquadList.Any(x => x.Value == roguelikeSquad) ? roguelikeSquad : string.Empty;
|
||||
}
|
||||
|
||||
public void UpdateRoguelikeCoreCharList()
|
||||
private void UpdateRoguelikeCoreCharList()
|
||||
{
|
||||
var filePath = $"resource/roguelike/{RoguelikeTheme}/recruitment.json";
|
||||
if (File.Exists(filePath) is false)
|
||||
|
||||
@@ -977,9 +977,6 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
AddLog(LocalizationHelper.GetString("AdbReplacementTips"), UiLogColor.Info);
|
||||
}
|
||||
|
||||
string errMsg = string.Empty;
|
||||
bool connected = await Task.Run(() => Instances.AsstProxy.AsstConnect(ref errMsg));
|
||||
|
||||
// 一般是点了“停止”按钮了
|
||||
if (Stopping)
|
||||
{
|
||||
@@ -1190,7 +1187,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
Instances.SettingsViewModel.CreditForceShoppingIfCreditFull);
|
||||
}
|
||||
|
||||
private bool AppendAward()
|
||||
private static bool AppendAward()
|
||||
{
|
||||
var receiveAward = Instances.SettingsViewModel.ReceiveAward;
|
||||
var receiveMail = Instances.SettingsViewModel.ReceiveMail;
|
||||
|
||||
@@ -449,7 +449,7 @@ namespace MaaWpfGui.ViewModels.UI
|
||||
/// 检查更新,并下载更新包。
|
||||
/// </summary>
|
||||
/// <returns>操作成功返回 <see langword="true"/>,反之则返回 <see langword="false"/>。</returns>
|
||||
public async Task<CheckUpdateRetT> CheckAndDownloadVersionUpdate()
|
||||
private async Task<CheckUpdateRetT> CheckAndDownloadVersionUpdate()
|
||||
{
|
||||
var checkResult = await CheckUpdateInner();
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
VerticalAlignment="Bottom"
|
||||
hc:BorderElement.CornerRadius="0,4,4,0"
|
||||
BorderThickness="0,1,1,1"
|
||||
Command="{s:Action AccountSwitchMannualRun}"
|
||||
Command="{s:Action AccountSwitchManualRun}"
|
||||
Content="{DynamicResource AccountSwitchManualRun}" />
|
||||
</Grid>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user