Files
MaaAssistantArknights/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs
2023-10-04 02:09:00 +08:00

3717 lines
134 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// <copyright file="SettingsViewModel.cs" company="MaaAssistantArknights">
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Management;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using HandyControl.Controls;
using HandyControl.Data;
using MaaWpfGui.Configuration;
using MaaWpfGui.Constants;
using MaaWpfGui.Extensions;
using MaaWpfGui.Helper;
using MaaWpfGui.Main;
using MaaWpfGui.Models;
using MaaWpfGui.Services.HotKeys;
using MaaWpfGui.Services.Notification;
using MaaWpfGui.States;
using MaaWpfGui.Utilities;
using MaaWpfGui.Utilities.ValueType;
using Microsoft.Win32;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
using Stylet;
using ComboBox = System.Windows.Controls.ComboBox;
using Timer = System.Timers.Timer;
namespace MaaWpfGui.ViewModels.UI
{
/// <summary>
/// The view model of settings.
/// </summary>
public class SettingsViewModel : Screen
{
private readonly RunningState _runningState;
private static readonly ILogger _logger = Log.ForContext<SettingsViewModel>();
[DllImport("MaaCore.dll")]
private static extern IntPtr AsstGetVersion();
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SWMINIMIZE = 6;
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
private static readonly string _versionId = Marshal.PtrToStringAnsi(AsstGetVersion());
/// <summary>
/// Gets the version id.
/// </summary>
public string VersionId => _versionId;
private static readonly string _versionInfo = LocalizationHelper.GetString("Version") + ": " + _versionId;
/// <summary>
/// Gets the version info.
/// </summary>
public string VersionInfo => _versionInfo;
/// <summary>
/// The Pallas language key.
/// </summary>
public static readonly string PallasLangKey = "pallas";
/// <summary>
/// Gets the visibility of task setting views.
/// </summary>
public TaskSettingVisibilityInfo TaskSettingVisibilities { get; } = TaskSettingVisibilityInfo.Current;
/// <summary>
/// Initializes a new instance of the <see cref="SettingsViewModel"/> class.
/// </summary>
public SettingsViewModel()
{
DisplayName = LocalizationHelper.GetString("Settings");
_listTitle.Add(LocalizationHelper.GetString("SwitchConfiguration"));
_listTitle.Add(LocalizationHelper.GetString("ScheduleSettings"));
_listTitle.Add(LocalizationHelper.GetString("GameSettings"));
_listTitle.Add(LocalizationHelper.GetString("ConnectionSettings"));
_listTitle.Add(LocalizationHelper.GetString("StartupSettings"));
_listTitle.Add(LocalizationHelper.GetString("UiSettings"));
_listTitle.Add(LocalizationHelper.GetString("ExternalNotificationSettings"));
_listTitle.Add(LocalizationHelper.GetString("HotKeySettings"));
_listTitle.Add(LocalizationHelper.GetString("UpdateSettings"));
_listTitle.Add(LocalizationHelper.GetString("AboutUs"));
InfrastInit();
SwitchDarkMode();
if (Hangover)
{
Hangover = false;
MessageBoxHelper.Show(
LocalizationHelper.GetString("Hangover"),
LocalizationHelper.GetString("Burping"),
MessageBoxButton.OK,
iconKey: "HangoverGeometry",
iconBrushKey: "PallasBrush");
Bootstrapper.ShutdownAndRestartWithOutArgs();
}
_runningState = RunningState.Instance;
}
public void Sober()
{
if (Cheers && Language == PallasLangKey)
{
ConfigurationHelper.SetValue(ConfigurationKeys.Localization, SoberLanguage);
Hangover = true;
Cheers = false;
}
}
protected override void OnInitialActivate()
{
base.OnInitialActivate();
var addressListJson = ConfigurationHelper.GetValue(ConfigurationKeys.AddressHistory, string.Empty);
if (!string.IsNullOrEmpty(addressListJson))
{
ConnectAddressHistory = JsonConvert.DeserializeObject<ObservableCollection<string>>(addressListJson);
}
}
#region External Notifications
// UI 绑定的方法
// ReSharper disable once UnusedMember.Global
public void ExternalNotificationSendTest()
{
ExternalNotificationService.Send(
LocalizationHelper.GetString("ExternalNotificationSendTestTitle"),
LocalizationHelper.GetString("ExternalNotificationSendTestContent"),
true);
}
public static List<CombinedData> ExternalNotificationProviders => new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("Off"), Value = "Off" },
new CombinedData { Display = "Server Chan", Value = "ServerChan" },
new CombinedData { Display = "SMTP", Value = "SMTP" },
};
private string _enabledExternalNotificationProvider = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationEnabled, "Off");
public bool IsEnabled => _enabledExternalNotificationProvider != "Off";
public bool IsServerChan => _enabledExternalNotificationProvider == "ServerChan";
public bool IsSmtp => _enabledExternalNotificationProvider == "SMTP";
public string EnabledExternalNotificationProvider
{
get => _enabledExternalNotificationProvider;
set
{
SetAndNotify(ref _enabledExternalNotificationProvider, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationEnabled, value);
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(IsSmtp));
NotifyOfPropertyChange(nameof(IsServerChan));
}
}
private string _serverChanSendKey = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationServerChanSendKey, string.Empty);
public string ServerChanSendKey
{
get => _serverChanSendKey;
set
{
SetAndNotify(ref _serverChanSendKey, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationServerChanSendKey, value);
}
}
private string _smtpServer = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpServer, string.Empty);
public string SmtpServer
{
get => _smtpServer;
set
{
SetAndNotify(ref _smtpServer, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpServer, value);
}
}
private string _smtpPort = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpPort, string.Empty);
public string SmtpPort
{
get => _smtpPort;
set
{
SetAndNotify(ref _smtpPort, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpPort, value);
}
}
private string _smtpUser = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpUser, string.Empty);
public string SmtpUser
{
get => _smtpUser;
set
{
SetAndNotify(ref _smtpUser, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpUser, value);
}
}
private string _smtpPassword = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpPassword, string.Empty);
public string SmtpPassword
{
get => _smtpPassword;
set
{
SetAndNotify(ref _smtpPassword, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpPassword, value);
}
}
private string _smtpFrom = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpFrom, string.Empty);
public string SmtpFrom
{
get => _smtpFrom;
set
{
SetAndNotify(ref _smtpFrom, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpFrom, value);
}
}
private string _smtpTo = ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpTo, string.Empty);
public string SmtpTo
{
get => _smtpTo;
set
{
SetAndNotify(ref _smtpTo, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpTo, value);
}
}
private bool _smtpUseSsl = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpUseSsl, "false"));
public bool SmtpUseSsl
{
get => _smtpUseSsl;
set
{
SetAndNotify(ref _smtpUseSsl, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpUseSsl, value.ToString());
}
}
private bool _smtpRequireAuthentication = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.ExternalNotificationSmtpRequiresAuthentication, "false"));
public bool SmtpRequireAuthentication
{
get => _smtpRequireAuthentication;
set
{
SetAndNotify(ref _smtpRequireAuthentication, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ExternalNotificationSmtpRequiresAuthentication, value.ToString());
}
}
#endregion External Notifications
private List<string> _listTitle = new List<string>();
/// <summary>
/// Gets or sets the list title.
/// </summary>
public List<string> ListTitle
{
get => _listTitle;
set => SetAndNotify(ref _listTitle, value);
}
private void InfrastInit()
{
/* 基建设置 */
var facilityList = new string[]
{
"Mfg",
"Trade",
"Control",
"Power",
"Reception",
"Office",
"Dorm",
"Processing",
};
var tempOrderList = new List<DragItemViewModel>(new DragItemViewModel[facilityList.Length]);
for (int i = 0; i != facilityList.Length; ++i)
{
var facility = facilityList[i];
bool parsed = int.TryParse(ConfigurationHelper.GetFacilityOrder(facility, "-1"), out int order);
if (!parsed || order < 0)
{
tempOrderList[i] = new DragItemViewModel(LocalizationHelper.GetString(facility), facility, "Infrast.");
}
else
{
tempOrderList[order] = new DragItemViewModel(LocalizationHelper.GetString(facility), facility, "Infrast.");
}
}
InfrastItemViewModels = new ObservableCollection<DragItemViewModel>(tempOrderList);
DefaultInfrastList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("UserDefined"), Value = _userDefined },
new CombinedData { Display = LocalizationHelper.GetString("153Time3"), Value = "153_layout_3_times_a_day.json" },
new CombinedData { Display = LocalizationHelper.GetString("243Time3"), Value = "243_layout_3_times_a_day.json" },
new CombinedData { Display = LocalizationHelper.GetString("243Time4"), Value = "243_layout_4_times_a_day.json" },
new CombinedData { Display = LocalizationHelper.GetString("252Time3"), Value = "252_layout_3_times_a_day.json" },
new CombinedData { Display = LocalizationHelper.GetString("333Time3"), Value = "333_layout_for_Orundum_3_times_a_day.json" },
};
UsesOfDronesList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("DronesNotUse"), Value = "_NotUse" },
new CombinedData { Display = LocalizationHelper.GetString("Money"), Value = "Money" },
new CombinedData { Display = LocalizationHelper.GetString("SyntheticJade"), Value = "SyntheticJade" },
new CombinedData { Display = LocalizationHelper.GetString("CombatRecord"), Value = "CombatRecord" },
new CombinedData { Display = LocalizationHelper.GetString("PureGold"), Value = "PureGold" },
new CombinedData { Display = LocalizationHelper.GetString("OriginStone"), Value = "OriginStone" },
new CombinedData { Display = LocalizationHelper.GetString("Chip"), Value = "Chip" },
};
ConnectConfigList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("General"), Value = "General" },
new CombinedData { Display = LocalizationHelper.GetString("BlueStacks"), Value = "BlueStacks" },
new CombinedData { Display = LocalizationHelper.GetString("MuMuEmulator"), Value = "MuMuEmulator" },
new CombinedData { Display = LocalizationHelper.GetString("MuMuEmulator12"), Value = "MuMuEmulator12" },
new CombinedData { Display = LocalizationHelper.GetString("LDPlayer"), Value = "LDPlayer" },
new CombinedData { Display = LocalizationHelper.GetString("Nox"), Value = "Nox" },
new CombinedData { Display = LocalizationHelper.GetString("XYAZ"), Value = "XYAZ" },
new CombinedData { Display = LocalizationHelper.GetString("WSA"), Value = "WSA" },
new CombinedData { Display = LocalizationHelper.GetString("Compatible"), Value = "Compatible" },
new CombinedData { Display = LocalizationHelper.GetString("SecondResolution"), Value = "SecondResolution" },
new CombinedData { Display = LocalizationHelper.GetString("GeneralWithoutScreencapErr"), Value = "GeneralWithoutScreencapErr" },
};
TouchModeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("MiniTouchMode"), Value = "minitouch" },
new CombinedData { Display = LocalizationHelper.GetString("MaaTouchMode"), Value = "maatouch" },
new CombinedData { Display = LocalizationHelper.GetString("AdbTouchMode"), Value = "adb" },
};
_dormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%";
RoguelikeModeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeStrategyExp"), Value = "0" },
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeStrategyGold"), Value = "1" },
// new CombData { Display = "两者兼顾,投资过后退出", Value = "2" } // 弃用
// new CombData { Display = Localization.GetString("3"), Value = "3" }, // 开发中
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeLastReward"), Value = "4" },
};
RoguelikeThemeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeThemePhantom"), Value = "Phantom" },
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeThemeMizuki"), Value = "Mizuki" },
new CombinedData { Display = LocalizationHelper.GetString("RoguelikeThemeSami"), Value = "Sami" },
};
UpdateRoguelikeSquadList();
UpdateRoguelikeCoreCharList();
RoguelikeRolesList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("DefaultRoles"), Value = string.Empty },
new CombinedData { Display = LocalizationHelper.GetString("FirstMoveAdvantage"), Value = "先手必胜" },
new CombinedData { Display = LocalizationHelper.GetString("SlowAndSteadyWinsTheRace"), Value = "稳扎稳打" },
new CombinedData { Display = LocalizationHelper.GetString("OvercomingYourWeaknesses"), Value = "取长补短" },
new CombinedData { Display = LocalizationHelper.GetString("AsYourHeartDesires"), Value = "随心所欲" },
};
ClientTypeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("NotSelected"), Value = string.Empty },
new CombinedData { Display = LocalizationHelper.GetString("Official"), Value = "Official" },
new CombinedData { Display = LocalizationHelper.GetString("Bilibili"), Value = "Bilibili" },
new CombinedData { Display = LocalizationHelper.GetString("YoStarEN"), Value = "YoStarEN" },
new CombinedData { Display = LocalizationHelper.GetString("YoStarJP"), Value = "YoStarJP" },
new CombinedData { Display = LocalizationHelper.GetString("YoStarKR"), Value = "YoStarKR" },
new CombinedData { Display = LocalizationHelper.GetString("Txwy"), Value = "txwy" },
};
var configurations = new ObservableCollection<CombinedData>();
foreach (var conf in ConfigurationHelper.GetConfigurationList())
{
configurations.Add(new CombinedData { Display = conf, Value = conf });
}
ConfigurationList = configurations;
DarkModeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("Light"), Value = "Light" },
new CombinedData { Display = LocalizationHelper.GetString("Dark"), Value = "Dark" },
new CombinedData { Display = LocalizationHelper.GetString("SyncWithOs"), Value = "SyncWithOs" },
};
InverseClearModeList = new List<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("Clear"), Value = "Clear" },
new CombinedData { Display = LocalizationHelper.GetString("Inverse"), Value = "Inverse" },
new CombinedData { Display = LocalizationHelper.GetString("Switchable"), Value = "ClearInverse" },
};
VersionTypeList = new List<GenericCombinedData<UpdateVersionType>>
{
new GenericCombinedData<UpdateVersionType> { Display = LocalizationHelper.GetString("UpdateCheckNightly"), Value = UpdateVersionType.Nightly },
new GenericCombinedData<UpdateVersionType> { Display = LocalizationHelper.GetString("UpdateCheckBeta"), Value = UpdateVersionType.Beta },
new GenericCombinedData<UpdateVersionType> { Display = LocalizationHelper.GetString("UpdateCheckStable"), Value = UpdateVersionType.Stable },
};
var languageList = new List<CombinedData>();
foreach (var pair in LocalizationHelper.SupportedLanguages)
{
if (pair.Key == PallasLangKey && !Cheers)
{
continue;
}
languageList.Add(new CombinedData { Display = pair.Value, Value = pair.Key });
}
LanguageList = languageList;
}
private bool _idle = true;
/// <summary>
/// Gets or sets a value indicating whether it is idle.
/// </summary>
public bool Idle
{
get => _idle;
set => SetAndNotify(ref _idle, value);
}
/* 启动设置 */
private bool _startSelf = AutoStart.CheckStart();
/// <summary>
/// Gets or sets a value indicating whether to start itself.
/// </summary>
public bool StartSelf
{
get => _startSelf;
set
{
SetAndNotify(ref _startSelf, value);
AutoStart.SetStart(value);
}
}
private bool _runDirectly = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RunDirectly, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to run directly.
/// </summary>
public bool RunDirectly
{
get => _runDirectly;
set
{
SetAndNotify(ref _runDirectly, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RunDirectly, value.ToString());
}
}
private bool _minimizeDirectly = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.MinimizeDirectly, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to minimize directly.
/// </summary>
public bool MinimizeDirectly
{
get => _minimizeDirectly;
set
{
SetAndNotify(ref _minimizeDirectly, value);
ConfigurationHelper.SetValue(ConfigurationKeys.MinimizeDirectly, value.ToString());
}
}
private bool _startEmulator = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.StartEmulator, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to start emulator.
/// </summary>
public bool StartEmulator
{
get => _startEmulator;
set
{
SetAndNotify(ref _startEmulator, value);
ConfigurationHelper.SetValue(ConfigurationKeys.StartEmulator, value.ToString());
if (ClientType == string.Empty && _runningState.GetIdle())
{
ClientType = "Official";
}
}
}
private string _accountName = ConfigurationHelper.GetValue(ConfigurationKeys.AccountName, string.Empty);
public string AccountName
{
get => _accountName;
set
{
SetAndNotify(ref _accountName, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AccountName, value);
}
}
// UI 绑定的方法
// ReSharper disable once UnusedMember.Global
public void AccountSwitchManualRun()
{
Instances.TaskQueueViewModel.QuickSwitchAccount();
}
private bool _minimizingStartup = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.MinimizingStartup, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to minimally start the emulator
/// </summary>
public bool MinimizingStartup
{
get => _minimizingStartup;
set
{
SetAndNotify(ref _minimizingStartup, value);
ConfigurationHelper.SetValue(ConfigurationKeys.MinimizingStartup, value.ToString());
}
}
private string _emulatorPath = ConfigurationHelper.GetValue(ConfigurationKeys.EmulatorPath, string.Empty);
/// <summary>
/// Gets or sets the emulator path.
/// </summary>
public string EmulatorPath
{
get => _emulatorPath;
set
{
SetAndNotify(ref _emulatorPath, value);
ConfigurationHelper.SetValue(ConfigurationKeys.EmulatorPath, value);
}
}
private string _emulatorAddCommand = ConfigurationHelper.GetValue(ConfigurationKeys.EmulatorAddCommand, string.Empty);
/// <summary>
/// Gets or sets the command to append after the emulator command.
/// </summary>
public string EmulatorAddCommand
{
get => _emulatorAddCommand;
set
{
SetAndNotify(ref _emulatorAddCommand, value);
ConfigurationHelper.SetValue(ConfigurationKeys.EmulatorAddCommand, value);
}
}
private string _emulatorWaitSeconds = ConfigurationHelper.GetValue(ConfigurationKeys.EmulatorWaitSeconds, "60");
/// <summary>
/// Gets or sets the seconds to wait for the emulator.
/// </summary>
public string EmulatorWaitSeconds
{
get => _emulatorWaitSeconds;
set
{
SetAndNotify(ref _emulatorWaitSeconds, value);
ConfigurationHelper.SetValue(ConfigurationKeys.EmulatorWaitSeconds, value);
}
}
private string _startsWithScript = ConfigurationHelper.GetValue(ConfigurationKeys.StartsWithScript, string.Empty);
public string StartsWithScript
{
get => _startsWithScript;
set
{
SetAndNotify(ref _startsWithScript, value);
ConfigurationHelper.SetValue(ConfigurationKeys.StartsWithScript, value);
}
}
private string _endsWithScript = ConfigurationHelper.GetValue(ConfigurationKeys.EndsWithScript, string.Empty);
public string EndsWithScript
{
get => _endsWithScript;
set
{
SetAndNotify(ref _endsWithScript, value);
ConfigurationHelper.SetValue(ConfigurationKeys.EndsWithScript, value);
}
}
public void RunScript(string str)
{
bool enable = str switch
{
"StartsWithScript" => !string.IsNullOrWhiteSpace(StartsWithScript),
"EndsWithScript" => !string.IsNullOrWhiteSpace(EndsWithScript),
_ => false,
};
if (enable)
{
Func<bool> func = str switch
{
"StartsWithScript" => RunStartCommand,
"EndsWithScript" => RunEndCommand,
_ => () => false,
};
Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog(
LocalizationHelper.GetString("StartTask") + LocalizationHelper.GetString(str)));
if (func())
{
Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog(
LocalizationHelper.GetString("CompleteTask") + LocalizationHelper.GetString(str)));
}
else
{
Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog(
LocalizationHelper.GetString("TaskError") + LocalizationHelper.GetString(str),
UiLogColor.Warning));
}
}
}
private bool RunStartCommand()
{
try
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = StartsWithScript,
WindowStyle = ProcessWindowStyle.Minimized,
// FileName = "cmd.exe",
// Arguments = $"/c {StartsWithScript}",
},
};
process.Start();
process.WaitForExit();
return true;
}
catch (Exception)
{
return false;
}
}
private bool RunEndCommand()
{
try
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = EndsWithScript,
WindowStyle = ProcessWindowStyle.Minimized,
// FileName = "cmd.exe",
// Arguments = $"/c {EndsWithScript}",
},
};
process.Start();
process.WaitForExit();
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Tries to start the emulator.
/// </summary>
/// <param name="manual">Whether to start manually.</param>
public void TryToStartEmulator(bool manual = false)
{
if (EmulatorPath.Length == 0
|| !File.Exists(EmulatorPath)
|| (!StartEmulator && !manual))
{
return;
}
if (!int.TryParse(EmulatorWaitSeconds, out int delay))
{
delay = 60;
}
try
{
string fileName = string.Empty;
string arguments = string.Empty;
ProcessStartInfo startInfo;
if (Path.GetExtension(EmulatorPath).ToLower() == ".lnk")
{
var link = (IShellLink)new ShellLink();
var file = (IPersistFile)link;
file.Load(EmulatorPath, 0); // STGM_READ
link.Resolve(IntPtr.Zero, 1); // SLR_NO_UI
var buf = new char[32768];
unsafe
{
fixed (char* ptr = buf)
{
link.GetPath(ptr, 260, IntPtr.Zero, 0); // MAX_PATH
var len = Array.IndexOf(buf, '\0');
if (len != -1)
{
fileName = new string(buf, 0, len);
}
link.GetArguments(ptr, 32768);
len = Array.IndexOf(buf, '\0');
if (len != -1)
{
arguments = new string(buf, 0, len);
}
}
}
}
else
{
fileName = EmulatorPath;
arguments = EmulatorAddCommand;
}
if (arguments.Length != 0)
{
startInfo = new ProcessStartInfo(fileName, arguments);
}
else
{
startInfo = new ProcessStartInfo(fileName);
}
startInfo.UseShellExecute = false;
Process process = new Process
{
StartInfo = startInfo,
};
_logger.Information("Try to start emulator: \nfileName: " + fileName + "\narguments: " + arguments);
process.Start();
try
{
// 如果之前就启动了模拟器,这步有几率会抛出异常
process.WaitForInputIdle();
if (MinimizingStartup)
{
_logger.Information("Try minimizing the emulator");
int i;
for (i = 0; !IsIconic(process.MainWindowHandle) && i < 100; ++i)
{
ShowWindow(process.MainWindowHandle, SWMINIMIZE);
Thread.Sleep(10);
if (process.HasExited)
{
throw new Exception();
}
}
if (i >= 100)
{
_logger.Information("Attempts to exceed the limit");
throw new Exception();
}
}
}
catch (Exception)
{
_logger.Information("The emulator was already start");
// 如果之前就启动了模拟器,如果开启了最小化启动,就把所有模拟器最小化
// TODO:只最小化需要开启的模拟器
string processName = Path.GetFileNameWithoutExtension(fileName);
Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length > 0)
{
if (MinimizingStartup)
{
_logger.Information("Try minimizing the emulator by processName: " + processName);
foreach (Process p in processes)
{
int i;
for (i = 0; !IsIconic(p.MainWindowHandle) && !p.HasExited && i < 100; ++i)
{
ShowWindow(p.MainWindowHandle, SWMINIMIZE);
Thread.Sleep(10);
}
if (i >= 100)
{
_logger.Warning("The emulator minimization failure");
}
}
}
}
}
}
catch (Exception)
{
_logger.Information("Start emulator error, try to start using the default: \n" +
"EmulatorPath: " + EmulatorPath + "\n" +
"EmulatorAddCommand: " + EmulatorAddCommand);
if (EmulatorAddCommand.Length != 0)
{
Process.Start(EmulatorPath);
}
else
{
Process.Start(EmulatorPath, EmulatorAddCommand);
}
}
// 储存按钮状态,以便后续重置
bool idle = _runningState.GetIdle();
// 让按钮变成停止按钮,可手动停止等待
_runningState.SetIdle(false);
for (var i = 0; i < delay; ++i)
{
if (Instances.TaskQueueViewModel.Stopping)
{
_logger.Information("Stop waiting for the emulator to start");
return;
}
if (i % 10 == 0)
{
Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog(
LocalizationHelper.GetString("WaitForEmulator") + ": " + (delay - i) + "s"));
_logger.Information("Waiting for the emulator to start: " + (delay - i) + "s");
}
Thread.Sleep(1000);
}
Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog(
LocalizationHelper.GetString("WaitForEmulatorFinish")));
_logger.Information("The wait is over");
// 重置按钮状态,不影响后续判断
_runningState.SetIdle(idle);
}
/// <summary>
/// Restarts the ADB (Android Debug Bridge).
/// </summary>
public void RestartAdb()
{
if (!AllowAdbRestart)
{
return;
}
string adbPath = AdbPath;
if (string.IsNullOrEmpty(adbPath))
{
return;
}
ProcessStartInfo processStartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
UseShellExecute = false,
};
Process process = new Process
{
StartInfo = processStartInfo,
};
process.Start();
process.StandardInput.WriteLine($"{adbPath} kill-server");
process.StandardInput.WriteLine($"{adbPath} start-server");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
}
/// <summary>
/// Kill and restart the ADB (Android Debug Bridge) process.
/// </summary>
public void HardRestartAdb()
{
if (!AllowAdbHardRestart)
{
return;
}
string adbPath = AdbPath;
if (string.IsNullOrEmpty(adbPath))
{
return;
}
// 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);
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)
{
if (item.Path != adbPath)
{
continue;
}
// Some emulators start their ADB with administrator privilege.
// Not sure if this is necessary
try
{
item.Process.Kill();
item.Process.WaitForExit();
}
catch
{
// ignored
}
}
}
/// <summary>
/// Selects the emulator to execute.
/// </summary>
public void SelectEmulatorExec()
{
var dialog = new OpenFileDialog
{
Filter = LocalizationHelper.GetString("Executable") + "|*.exe;*.bat;*.lnk",
};
if (dialog.ShowDialog() == true)
{
EmulatorPath = dialog.FileName;
}
}
private string _clientType = ConfigurationHelper.GetValue(ConfigurationKeys.ClientType, "Official");
/// <summary>
/// Gets or sets the client type.
/// </summary>
public string ClientType
{
get => _clientType;
set
{
SetAndNotify(ref _clientType, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ClientType, value);
UpdateWindowTitle(); /* 每次修改客户端时更新WindowTitle */
Instances.TaskQueueViewModel.UpdateStageList(true);
Instances.TaskQueueViewModel.UpdateDatePrompt();
Instances.AsstProxy.LoadResource();
}
}
/// <summary>
/// Gets the client type.
/// </summary>
public string ClientName
{
get
{
foreach (var item in ClientTypeList)
{
if (item.Value == ClientType)
{
return item.Display;
}
}
return "Unknown Client";
}
}
private readonly Dictionary<string, string> _serverMapping = new Dictionary<string, string>
{
{ string.Empty, "CN" },
{ "Official", "CN" },
{ "Bilibili", "CN" },
{ "YoStarEN", "US" },
{ "YoStarJP", "JP" },
{ "YoStarKR", "KR" },
{ "txwy", "ZH_TW" },
};
private bool _autoRestartOnDrop = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.AutoRestartOnDrop, "True"));
public bool AutoRestartOnDrop
{
get => _autoRestartOnDrop;
set
{
SetAndNotify(ref _autoRestartOnDrop, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AutoRestartOnDrop, value.ToString());
}
}
/// <summary>
/// Gets the server type.
/// </summary>
public string ServerType => _serverMapping[ClientType];
/* 基建设置 */
/// <summary>
/// Gets or sets the infrast item view models.
/// </summary>
public ObservableCollection<DragItemViewModel> InfrastItemViewModels { get; set; }
/// <summary>
/// Gets or sets the list of uses of drones.
/// </summary>
public List<CombinedData> UsesOfDronesList { get; set; }
/// <summary>
/// Gets or sets the list of uses of default infrast.
/// </summary>
public List<CombinedData> DefaultInfrastList { get; set; }
/// <summary>
/// Gets or sets the list of roguelike lists.
/// </summary>
public List<CombinedData> RoguelikeThemeList { get; set; }
/// <summary>
/// Gets or sets the list of roguelike modes.
/// </summary>
public List<CombinedData> RoguelikeModeList { get; set; }
private ObservableCollection<CombinedData> _roguelikeSquadList = new ObservableCollection<CombinedData>();
/// <summary>
/// Gets or sets the list of roguelike squad.
/// </summary>
public ObservableCollection<CombinedData> RoguelikeSquadList
{
get => _roguelikeSquadList;
set => SetAndNotify(ref _roguelikeSquadList, value);
}
/// <summary>
/// Gets or sets the list of roguelike roles.
/// </summary>
public List<CombinedData> RoguelikeRolesList { get; set; }
// public List<CombData> RoguelikeCoreCharList { get; set; }
/// <summary>
/// Gets or sets the list of the client types.
/// </summary>
public List<CombinedData> ClientTypeList { get; set; }
public ObservableCollection<CombinedData> ConfigurationList { get; set; }
private string _currentConfiguration = ConfigurationHelper.GetCurrentConfiguration();
public string CurrentConfiguration
{
get => _currentConfiguration;
set
{
SetAndNotify(ref _currentConfiguration, value);
ConfigurationHelper.SwitchConfiguration(value);
Bootstrapper.ShutdownAndRestartWithOutArgs();
}
}
private string _newConfigurationName;
public string NewConfigurationName
{
get => _newConfigurationName;
set => SetAndNotify(ref _newConfigurationName, value);
}
public void AddConfiguration()
{
if (string.IsNullOrEmpty(NewConfigurationName))
{
NewConfigurationName = DateTime.Now.ToString("yy/MM/dd HH:mm:ss");
}
if (ConfigurationHelper.AddConfiguration(NewConfigurationName, CurrentConfiguration))
{
ConfigurationList.Add(new CombinedData { Display = NewConfigurationName, Value = NewConfigurationName });
var growinfo = new GrowlInfo
{
IsCustom = true,
Message = string.Format(LocalizationHelper.GetString("AddConfigSuccess"), NewConfigurationName),
IconKey = "HangoverGeometry",
IconBrushKey = "PallasBrush",
};
Growl.Info(growinfo);
}
else
{
var growinfo = new GrowlInfo
{
IsCustom = true,
Message = string.Format(LocalizationHelper.GetString("ConfigExists"), NewConfigurationName),
IconKey = "HangoverGeometry",
IconBrushKey = "PallasBrush",
};
Growl.Info(growinfo);
}
}
public void DeleteConfiguration(CombinedData delete)
{
if (ConfigurationHelper.DeleteConfiguration(delete.Display))
{
ConfigurationList.Remove(delete);
}
}
/// <summary>
/// Gets or sets the list of the configuration of connection.
/// </summary>
public List<CombinedData> ConnectConfigList { get; set; }
/// <summary>
/// Gets or sets the list of touch modes
/// </summary>
public List<CombinedData> TouchModeList { get; set; }
/// <summary>
/// Gets or sets the list of dark mode.
/// </summary>
public List<CombinedData> DarkModeList { get; set; }
/// <summary>
/// Gets or sets the list of inverse clear modes.
/// </summary>
public List<CombinedData> InverseClearModeList { get; set; }
/// <summary>
/// Gets or sets the list of the version type.
/// </summary>
public List<GenericCombinedData<UpdateVersionType>> VersionTypeList { get; set; }
/// <summary>
/// Gets or sets the language list.
/// </summary>
public List<CombinedData> LanguageList { get; set; }
private int _dormThreshold = Convert.ToInt32(ConfigurationHelper.GetValue(ConfigurationKeys.DormThreshold, "30"));
/// <summary>
/// Gets or sets the threshold to enter dormitory.
/// </summary>
public int DormThreshold
{
get => _dormThreshold;
set
{
SetAndNotify(ref _dormThreshold, value);
DormThresholdLabel = LocalizationHelper.GetString("DormThreshold") + ": " + _dormThreshold + "%";
ConfigurationHelper.SetValue(ConfigurationKeys.DormThreshold, value.ToString());
}
}
private string _dormThresholdLabel;
/// <summary>
/// Gets or sets the label of dormitory threshold.
/// </summary>
public string DormThresholdLabel
{
get => _dormThresholdLabel;
set => SetAndNotify(ref _dormThresholdLabel, value);
}
/// <summary>
/// Gets infrast order list.
/// </summary>
/// <returns>The infrast order list.</returns>
public List<string> GetInfrastOrderList()
{
var orderList = new List<string>();
foreach (var item in InfrastItemViewModels)
{
if (item.IsChecked == false)
{
continue;
}
orderList.Add(item.OriginalName);
}
return orderList;
}
/// <summary>
/// 实时更新基建换班顺序
/// </summary>
public void InfrastOrderSelectionChanged()
{
int index = 0;
foreach (var item in InfrastItemViewModels)
{
ConfigurationHelper.SetFacilityOrder(item.OriginalName, index.ToString());
++index;
}
}
public TaskQueueViewModel CustomInfrastPlanDataContext { get => Instances.TaskQueueViewModel; }
private string _usesOfDrones = ConfigurationHelper.GetValue(ConfigurationKeys.UsesOfDrones, "Money");
/// <summary>
/// Gets or sets the uses of drones.
/// </summary>
public string UsesOfDrones
{
get => _usesOfDrones;
set
{
SetAndNotify(ref _usesOfDrones, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UsesOfDrones, value);
}
}
private string _defaultInfrast = ConfigurationHelper.GetValue(ConfigurationKeys.DefaultInfrast, _userDefined);
private static readonly string _userDefined = "user_defined";
/// <summary>
/// Gets or sets the uses of drones.
/// </summary>
public string DefaultInfrast
{
get => _defaultInfrast;
set
{
SetAndNotify(ref _defaultInfrast, value);
if (_defaultInfrast != _userDefined)
{
CustomInfrastFile = "resource\\custom_infrast\\" + value;
IsCustomInfrastFileReadOnly = true;
}
else
{
IsCustomInfrastFileReadOnly = false;
}
ConfigurationHelper.SetValue(ConfigurationKeys.DefaultInfrast, value);
}
}
private string _isCustomInfrastFileReadOnly = ConfigurationHelper.GetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether CustomInfrastFile is read-only
/// </summary>
public bool IsCustomInfrastFileReadOnly
{
get => bool.Parse(_isCustomInfrastFileReadOnly);
set
{
SetAndNotify(ref _isCustomInfrastFileReadOnly, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.IsCustomInfrastFileReadOnly, value.ToString());
}
}
private string _dormFilterNotStationedEnabled = ConfigurationHelper.GetValue(ConfigurationKeys.DormFilterNotStationedEnabled, true.ToString());
/// <summary>
/// Gets or sets a value indicating whether the not stationed filter in dorm is enabled.
/// </summary>
public bool DormFilterNotStationedEnabled
{
get => bool.Parse(_dormFilterNotStationedEnabled);
set
{
SetAndNotify(ref _dormFilterNotStationedEnabled, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.DormFilterNotStationedEnabled, value.ToString());
}
}
private string _dormTrustEnabled = ConfigurationHelper.GetValue(ConfigurationKeys.DormTrustEnabled, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether get trust in dorm is enabled.
/// </summary>
public bool DormTrustEnabled
{
get => bool.Parse(_dormTrustEnabled);
set
{
SetAndNotify(ref _dormTrustEnabled, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.DormTrustEnabled, value.ToString());
}
}
private string _originiumShardAutoReplenishment = ConfigurationHelper.GetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, true.ToString());
/// <summary>
/// Gets or sets a value indicating whether Originium shard auto replenishment is enabled.
/// </summary>
public bool OriginiumShardAutoReplenishment
{
get => bool.Parse(_originiumShardAutoReplenishment);
set
{
SetAndNotify(ref _originiumShardAutoReplenishment, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.OriginiumShardAutoReplenishment, value.ToString());
}
}
private bool _customInfrastEnabled = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastEnabled, false.ToString()));
public bool CustomInfrastEnabled
{
get => _customInfrastEnabled;
set
{
SetAndNotify(ref _customInfrastEnabled, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastEnabled, value.ToString());
Instances.TaskQueueViewModel.CustomInfrastEnabled = value;
}
}
/// <summary>
/// Selects infrast config file.
/// </summary>
public void SelectCustomInfrastFile()
{
var dialog = new OpenFileDialog
{
Filter = LocalizationHelper.GetString("CustomInfrastFile") + "|*.json",
};
if (dialog.ShowDialog() == true)
{
CustomInfrastFile = dialog.FileName;
}
DefaultInfrast = _userDefined;
}
private string _customInfrastFile = ConfigurationHelper.GetValue(ConfigurationKeys.CustomInfrastFile, string.Empty);
public string CustomInfrastFile
{
get => _customInfrastFile;
set
{
SetAndNotify(ref _customInfrastFile, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CustomInfrastFile, value);
Instances.TaskQueueViewModel.RefreshCustomInfrastPlan();
}
}
#region
private enum NotifyType
{
None,
SelectedIndex,
ScrollOffset,
}
private NotifyType _notifySource = NotifyType.None;
private Timer _resetNotifyTimer;
private void ResetNotifySource()
{
if (_resetNotifyTimer != null)
{
_resetNotifyTimer.Stop();
_resetNotifyTimer.Close();
}
_resetNotifyTimer = new Timer(20);
_resetNotifyTimer.Elapsed += (source, e) =>
{
_notifySource = NotifyType.None;
};
_resetNotifyTimer.AutoReset = false;
_resetNotifyTimer.Enabled = true;
_resetNotifyTimer.Start();
}
/// <summary>
/// Gets or sets the height of scroll viewport.
/// </summary>
public double ScrollViewportHeight { get; set; }
/// <summary>
/// Gets or sets the extent height of scroll.
/// </summary>
public double ScrollExtentHeight { get; set; }
/// <summary>
/// Gets or sets the list of divider vertical offset.
/// </summary>
public List<double> DividerVerticalOffsetList { get; set; }
private int _selectedIndex = 0;
/// <summary>
/// Gets or sets the index selected.
/// </summary>
public int SelectedIndex
{
get => _selectedIndex;
set
{
switch (_notifySource)
{
case NotifyType.None:
_notifySource = NotifyType.SelectedIndex;
SetAndNotify(ref _selectedIndex, value);
var isInRange = DividerVerticalOffsetList != null
&& DividerVerticalOffsetList.Count > 0
&& value < DividerVerticalOffsetList.Count;
if (isInRange)
{
ScrollOffset = DividerVerticalOffsetList[value];
}
ResetNotifySource();
break;
case NotifyType.ScrollOffset:
SetAndNotify(ref _selectedIndex, value);
break;
}
}
}
private double _scrollOffset = 0;
/// <summary>
/// Gets or sets the scroll offset.
/// </summary>
public double ScrollOffset
{
get => _scrollOffset;
set
{
switch (_notifySource)
{
case NotifyType.None:
_notifySource = NotifyType.ScrollOffset;
SetAndNotify(ref _scrollOffset, value);
// 设置 ListBox SelectedIndex 为当前 ScrollOffset 索引
var isInRange = DividerVerticalOffsetList != null && DividerVerticalOffsetList.Count > 0;
if (isInRange)
{
// 滚动条滚动到底部,返回最后一个 Divider 索引
if (value + ScrollViewportHeight >= ScrollExtentHeight)
{
SelectedIndex = DividerVerticalOffsetList.Count - 1;
ResetNotifySource();
break;
}
// 根据出当前 ScrollOffset 选出最后一个在可视范围的 Divider 索引
var dividerSelect = DividerVerticalOffsetList.Select((n, i) => (
dividerAppeared: value >= n,
index: i));
var index = dividerSelect.LastOrDefault(n => n.dividerAppeared).index;
SelectedIndex = index;
}
ResetNotifySource();
break;
case NotifyType.SelectedIndex:
SetAndNotify(ref _scrollOffset, value);
break;
}
}
}
#endregion
/* 肉鸽设置 */
private string _roguelikeTheme = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeTheme, "Sami");
/// <summary>
/// Gets or sets the Roguelike theme.
/// </summary>
public string RoguelikeTheme
{
get => _roguelikeTheme;
set
{
SetAndNotify(ref _roguelikeTheme, value);
UpdateRoguelikeSquadList();
UpdateRoguelikeCoreCharList();
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeTheme, value);
}
}
private string _roguelikeMode = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeMode, "0");
/// <summary>
/// 策略,往后打 / 刷一层就退 / 烧热水
/// </summary>
public string RoguelikeMode
{
get => _roguelikeMode;
set
{
SetAndNotify(ref _roguelikeMode, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeMode, value);
}
}
private string _roguelikeSquad = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeSquad, string.Empty);
/// <summary>
/// Gets or sets the roguelike squad.
/// </summary>
public string RoguelikeSquad
{
get => _roguelikeSquad;
set
{
SetAndNotify(ref _roguelikeSquad, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeSquad, value);
}
}
private string _roguelikeRoles = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeRoles, string.Empty);
/// <summary>
/// Gets or sets the roguelike roles.
/// </summary>
public string RoguelikeRoles
{
get => _roguelikeRoles;
set
{
SetAndNotify(ref _roguelikeRoles, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeRoles, value);
}
}
private string _roguelikeCoreChar = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeCoreChar, string.Empty);
/// <summary>
/// Gets or sets the roguelike core character.
/// </summary>
public string RoguelikeCoreChar
{
get => _roguelikeCoreChar;
set
{
if (_roguelikeCoreChar == (value ??= string.Empty))
{
return;
}
SetAndNotify(ref _roguelikeCoreChar, value);
Instances.TaskQueueViewModel.AddLog(value);
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeCoreChar, value);
}
}
private ObservableCollection<string> _roguelikeCoreCharList = new ObservableCollection<string>();
/// <summary>
/// Gets or sets the roguelike core character.
/// </summary>
public ObservableCollection<string> RoguelikeCoreCharList
{
get => _roguelikeCoreCharList;
private set => SetAndNotify(ref _roguelikeCoreCharList, value);
}
private string _roguelikeStartWithEliteTwo = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeStartWithEliteTwo, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether use support unit.
/// </summary>
public bool RoguelikeStartWithEliteTwo
{
get => bool.Parse(_roguelikeStartWithEliteTwo);
set
{
if (value && RoguelikeUseSupportUnit)
{
RoguelikeUseSupportUnit = false;
}
SetAndNotify(ref _roguelikeStartWithEliteTwo, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeStartWithEliteTwo, value.ToString());
}
}
private string _roguelikeUseSupportUnit = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeUseSupportUnit, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether use support unit.
/// </summary>
public bool RoguelikeUseSupportUnit
{
get => bool.Parse(_roguelikeUseSupportUnit);
set
{
if (value && RoguelikeStartWithEliteTwo)
{
RoguelikeStartWithEliteTwo = false;
}
SetAndNotify(ref _roguelikeUseSupportUnit, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeUseSupportUnit, value.ToString());
}
}
private string _roguelikeEnableNonfriendSupport = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeEnableNonfriendSupport, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether can roguelike support unit belong to nonfriend
/// </summary>
public bool RoguelikeEnableNonfriendSupport
{
get => bool.Parse(_roguelikeEnableNonfriendSupport);
set
{
SetAndNotify(ref _roguelikeEnableNonfriendSupport, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeEnableNonfriendSupport, value.ToString());
}
}
private string _roguelikeStartsCount = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeStartsCount, "9999999");
/// <summary>
/// Gets or sets the start count of roguelike.
/// </summary>
public int RoguelikeStartsCount
{
get => int.Parse(_roguelikeStartsCount);
set
{
SetAndNotify(ref _roguelikeStartsCount, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeStartsCount, value.ToString());
}
}
private string _roguelikeInvestmentEnabled = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeInvestmentEnabled, true.ToString());
/// <summary>
/// Gets or sets a value indicating whether investment is enabled.
/// </summary>
public bool RoguelikeInvestmentEnabled
{
get => bool.Parse(_roguelikeInvestmentEnabled);
set
{
SetAndNotify(ref _roguelikeInvestmentEnabled, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeInvestmentEnabled, value.ToString());
}
}
private string _roguelikeInvestmentEnterSecondFloor = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeInvestmentEnterSecondFloor, true.ToString());
/// <summary>
/// Gets or sets a value indicating whether investment is enabled.
/// </summary>
public bool RoguelikeInvestmentEnterSecondFloor
{
get => bool.Parse(_roguelikeInvestmentEnterSecondFloor);
set
{
SetAndNotify(ref _roguelikeInvestmentEnterSecondFloor, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeInvestmentEnterSecondFloor, value.ToString());
}
}
private string _roguelikeRefreshTraderWithDice = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeRefreshTraderWithDice, false.ToString());
public bool RoguelikeRefreshTraderWithDice
{
get => bool.Parse(_roguelikeRefreshTraderWithDice);
set
{
SetAndNotify(ref _roguelikeRefreshTraderWithDice, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeRefreshTraderWithDice, value.ToString());
}
}
private string _roguelikeInvestsCount = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeInvestsCount, "9999999");
/// <summary>
/// Gets or sets the invests count of roguelike.
/// </summary>
public int RoguelikeInvestsCount
{
get => int.Parse(_roguelikeInvestsCount);
set
{
SetAndNotify(ref _roguelikeInvestsCount, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeInvestsCount, value.ToString());
}
}
private string _roguelikeStopWhenInvestmentFull = ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeStopWhenInvestmentFull, false.ToString());
/// <summary>
/// Gets or sets a value indicating whether to stop when investment is full.
/// </summary>
public bool RoguelikeStopWhenInvestmentFull
{
get => bool.Parse(_roguelikeStopWhenInvestmentFull);
set
{
SetAndNotify(ref _roguelikeStopWhenInvestmentFull, value.ToString());
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeStopWhenInvestmentFull, value.ToString());
}
}
/* 访问好友设置 */
private string _lastCreditFightTaskTime = ConfigurationHelper.GetValue(ConfigurationKeys.LastCreditFightTaskTime, DateTime.UtcNow.ToYjDate().AddDays(-1).ToString("yyyy/MM/dd HH:mm:ss"));
public string LastCreditFightTaskTime
{
get => _lastCreditFightTaskTime;
set
{
SetAndNotify(ref _lastCreditFightTaskTime, value);
ConfigurationHelper.SetValue(ConfigurationKeys.LastCreditFightTaskTime, value.ToString());
}
}
private bool _creditFightTaskEnabled = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.CreditFightTaskEnabled, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether credit fight task is enabled.
/// </summary>
public bool CreditFightTaskEnabled
{
get
{
try
{
if (DateTime.UtcNow.ToYjDate() > DateTime.ParseExact(_lastCreditFightTaskTime.Replace('-', '/'), "yyyy/MM/dd HH:mm:ss", CultureInfo.InvariantCulture))
{
return _creditFightTaskEnabled;
}
}
catch
{
return _creditFightTaskEnabled;
}
return false;
}
set
{
SetAndNotify(ref _creditFightTaskEnabled, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditFightTaskEnabled, value.ToString());
}
}
public bool CreditFightTaskEnabledDisplay
{
get
{
return _creditFightTaskEnabled;
}
set
{
SetAndNotify(ref _creditFightTaskEnabled, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditFightTaskEnabled, value.ToString());
}
}
/* 信用商店设置 */
private bool _creditShopping = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.CreditShopping, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to shop with credit.
/// </summary>
public bool CreditShopping
{
get => _creditShopping;
set
{
SetAndNotify(ref _creditShopping, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditShopping, value.ToString());
}
}
private string _creditFirstList = ConfigurationHelper.GetValue(ConfigurationKeys.CreditFirstListNew, LocalizationHelper.GetString("HighPriorityDefault"));
/// <summary>
/// Gets or sets the priority item list of credit shop.
/// </summary>
public string CreditFirstList
{
get => _creditFirstList;
set
{
SetAndNotify(ref _creditFirstList, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditFirstListNew, value);
}
}
private string _creditBlackList = ConfigurationHelper.GetValue(ConfigurationKeys.CreditBlackListNew, LocalizationHelper.GetString("BlacklistDefault"));
/// <summary>
/// Gets or sets the blacklist of credit shop.
/// </summary>
public string CreditBlackList
{
get => _creditBlackList;
set
{
SetAndNotify(ref _creditBlackList, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditBlackListNew, value);
}
}
private bool _creditForceShoppingIfCreditFull = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.CreditForceShoppingIfCreditFull, false.ToString()));
/// <summary>
/// Gets or sets a value indicating whether save credit is enabled.
/// </summary>
public bool CreditForceShoppingIfCreditFull
{
get => _creditForceShoppingIfCreditFull;
set
{
SetAndNotify(ref _creditForceShoppingIfCreditFull, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CreditForceShoppingIfCreditFull, value.ToString());
}
}
/* 领取奖励设置 */
private bool _receiveAward = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.ReceiveAward, true.ToString()));
/// <summary>
/// Gets or sets a value indicating whether receive award is enabled.
/// </summary>
public bool ReceiveAward
{
get => _receiveAward;
set
{
SetAndNotify(ref _receiveAward, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ReceiveAward, value.ToString());
}
}
private bool _receiveMail = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.ReceiveMail, false.ToString()));
/// <summary>
/// Gets or sets a value indicating whether receive mail is enabled.
/// </summary>
public bool ReceiveMail
{
get => _receiveMail;
set
{
SetAndNotify(ref _receiveMail, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ReceiveMail, value.ToString());
}
}
/* 定时设置 */
public class TimerModel
{
public class TimerProperties : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public TimerProperties(int timeId, bool isOn, int hour, int min, string timerConfig)
{
TimerId = timeId;
_isOn = isOn;
_hour = hour;
_min = min;
if (timerConfig == null || !ConfigurationHelper.GetConfigurationList().Contains(timerConfig))
{
_timerConfig = ConfigurationHelper.GetCurrentConfiguration();
}
else
{
_timerConfig = timerConfig;
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public int TimerId { get; set; }
private bool _isOn;
/// <summary>
/// Gets or sets a value indicating whether the timer is set.
/// </summary>
public bool IsOn
{
get => _isOn;
set
{
_isOn = value;
OnPropertyChanged();
ConfigurationHelper.SetTimer(TimerId, value.ToString());
}
}
private int _hour;
/// <summary>
/// Gets or sets the hour of the timer.
/// </summary>
public int Hour
{
get => _hour;
set
{
_hour = (value >= 0 && value <= 23) ? value : _hour;
OnPropertyChanged();
ConfigurationHelper.SetTimerHour(TimerId, _hour.ToString());
}
}
private int _min;
/// <summary>
/// Gets or sets the minute of the timer.
/// </summary>
public int Min
{
get => _min;
set
{
_min = (value >= 0 && value <= 59) ? value : _min;
OnPropertyChanged();
ConfigurationHelper.SetTimerMin(TimerId, _min.ToString());
}
}
private string _timerConfig;
/// <summary>
/// Gets or sets the config of the timer.
/// </summary>
public string TimerConfig
{
get => _timerConfig;
set
{
_timerConfig = value ?? ConfigurationHelper.GetCurrentConfiguration();
OnPropertyChanged();
ConfigurationHelper.SetTimerConfig(TimerId, _timerConfig.ToString());
}
}
public TimerProperties()
{
PropertyChanged += (sender, args) => { };
}
}
public TimerProperties[] Timers { get; set; } = new TimerProperties[8];
public TimerModel()
{
for (int i = 0; i < 8; i++)
{
Timers[i] = new TimerProperties(
i,
ConfigurationHelper.GetTimer(i, bool.FalseString) == bool.TrueString,
int.Parse(ConfigurationHelper.GetTimerHour(i, $"{i * 3}")),
int.Parse(ConfigurationHelper.GetTimerMin(i, "0")),
ConfigurationHelper.GetTimerConfig(i, ConfigurationHelper.GetCurrentConfiguration()));
}
}
}
public TimerModel TimerModels { get; set; } = new TimerModel();
private bool _forceScheduledStart = Convert.ToBoolean(ConfigurationHelper.GetGlobalValue(ConfigurationKeys.ForceScheduledStart, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to use DrGrandet mode.
/// </summary>
public bool ForceScheduledStart
{
get => _forceScheduledStart;
set
{
SetAndNotify(ref _forceScheduledStart, value);
ConfigurationHelper.SetGlobalValue(ConfigurationKeys.ForceScheduledStart, value.ToString());
}
}
private bool _customConfig = Convert.ToBoolean(ConfigurationHelper.GetGlobalValue(ConfigurationKeys.CustomConfig, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to use custom config.
/// </summary>
public bool CustomConfig
{
get => _customConfig;
set
{
SetAndNotify(ref _customConfig, value);
ConfigurationHelper.SetGlobalValue(ConfigurationKeys.CustomConfig, value.ToString());
}
}
/* 刷理智设置 */
private string _penguinId = ConfigurationHelper.GetValue(ConfigurationKeys.PenguinId, string.Empty);
/// <summary>
/// Gets or sets the id of PenguinStats.
/// </summary>
public string PenguinId
{
get => _penguinId;
set
{
SetAndNotify(ref _penguinId, value);
ConfigurationHelper.SetValue(ConfigurationKeys.PenguinId, value);
}
}
private bool _isDrGrandet = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.IsDrGrandet, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to use DrGrandet mode.
/// </summary>
public bool IsDrGrandet
{
get => _isDrGrandet;
set
{
SetAndNotify(ref _isDrGrandet, value);
ConfigurationHelper.SetValue(ConfigurationKeys.IsDrGrandet, value.ToString());
}
}
/* 自动公招设置 */
private string _recruitMaxTimes = ConfigurationHelper.GetValue(ConfigurationKeys.RecruitMaxTimes, "4");
/// <summary>
/// Gets or sets the maximum times of recruit.
/// </summary>
public string RecruitMaxTimes
{
get => _recruitMaxTimes;
set
{
SetAndNotify(ref _recruitMaxTimes, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RecruitMaxTimes, value);
}
}
private bool _refreshLevel3 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RefreshLevel3, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to refresh level 3.
/// </summary>
public bool RefreshLevel3
{
get => _refreshLevel3;
set
{
SetAndNotify(ref _refreshLevel3, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RefreshLevel3, value.ToString());
}
}
private bool _useExpedited = false;
/// <summary>
/// Gets or sets a value indicating whether to use expedited.
/// </summary>
public bool UseExpedited
{
get => _useExpedited;
set => SetAndNotify(ref _useExpedited, value);
}
private bool _isLevel3UseShortTime = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.IsLevel3UseShortTime, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to shorten the time for level 3.
/// </summary>
public bool IsLevel3UseShortTime
{
get => _isLevel3UseShortTime;
set
{
if (value)
{
IsLevel3UseShortTime2 = false;
}
SetAndNotify(ref _isLevel3UseShortTime, value);
ConfigurationHelper.SetValue(ConfigurationKeys.IsLevel3UseShortTime, value.ToString());
}
}
private bool _isLevel3UseShortTime2 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.IsLevel3UseShortTime2, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to shorten the time for level 3.
/// </summary>
public bool IsLevel3UseShortTime2
{
get => _isLevel3UseShortTime2;
set
{
if (value)
{
IsLevel3UseShortTime = false;
}
SetAndNotify(ref _isLevel3UseShortTime2, value);
ConfigurationHelper.SetValue(ConfigurationKeys.IsLevel3UseShortTime2, value.ToString());
}
}
private bool _notChooseLevel1 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.NotChooseLevel1, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether not to choose level 1.
/// </summary>
public bool NotChooseLevel1
{
get => _notChooseLevel1;
set
{
SetAndNotify(ref _notChooseLevel1, value);
ConfigurationHelper.SetValue(ConfigurationKeys.NotChooseLevel1, value.ToString());
}
}
private bool _chooseLevel3 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RecruitChooseLevel3, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to choose level 3.
/// </summary>
public bool ChooseLevel3
{
get => _chooseLevel3;
set
{
SetAndNotify(ref _chooseLevel3, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RecruitChooseLevel3, value.ToString());
}
}
private bool _chooseLevel4 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RecruitChooseLevel4, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to choose level 4.
/// </summary>
public bool ChooseLevel4
{
get => _chooseLevel4;
set
{
SetAndNotify(ref _chooseLevel4, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RecruitChooseLevel4, value.ToString());
}
}
private bool _chooseLevel5 = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RecruitChooseLevel5, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to choose level 5.
/// </summary>
public bool ChooseLevel5
{
get => _chooseLevel5;
set
{
SetAndNotify(ref _chooseLevel5, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RecruitChooseLevel5, value.ToString());
}
}
public enum UpdateVersionType
{
/// <summary>
/// 测试版
/// </summary>
Nightly,
/// <summary>
/// 开发版
/// </summary>
Beta,
/// <summary>
/// 稳定版
/// </summary>
Stable,
}
/* 软件更新设置 */
private UpdateVersionType _versionType = (UpdateVersionType)Enum.Parse(typeof(UpdateVersionType),
ConfigurationHelper.GetValue(ConfigurationKeys.VersionType, UpdateVersionType.Stable.ToString()));
/// <summary>
/// Gets or sets the type of version to update.
/// </summary>
public UpdateVersionType VersionType
{
get => _versionType;
set
{
SetAndNotify(ref _versionType, value);
ConfigurationHelper.SetValue(ConfigurationKeys.VersionType, value.ToString());
}
}
/// <summary>
/// Gets a value indicating whether to update nightly.
/// </summary>
public bool UpdateNightly
{
get => _versionType == UpdateVersionType.Nightly;
}
/// <summary>
/// Gets a value indicating whether to update beta version.
/// </summary>
public bool UpdateBeta
{
get => _versionType == UpdateVersionType.Beta;
}
private bool _updateCheck = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.UpdateCheck, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to check update.
/// </summary>
public bool UpdateCheck
{
get => _updateCheck;
set
{
SetAndNotify(ref _updateCheck, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UpdateCheck, value.ToString());
}
}
private bool _updateAutoCheck = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.UpdateAutoCheck, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to check update.
/// </summary>
public bool UpdateAutoCheck
{
get => _updateAutoCheck;
set
{
SetAndNotify(ref _updateAutoCheck, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UpdateAutoCheck, value.ToString());
}
}
private string _proxy = ConfigurationHelper.GetValue(ConfigurationKeys.UpdateProxy, string.Empty);
/// <summary>
/// Gets or sets the proxy settings.
/// </summary>
public string Proxy
{
get => _proxy;
set
{
SetAndNotify(ref _proxy, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UpdateProxy, value);
}
}
private bool _isCheckingForUpdates = false;
/// <summary>
/// Gets or sets a value indicating whether the update is being checked.
/// </summary>
public bool IsCheckingForUpdates
{
get => _isCheckingForUpdates;
set
{
SetAndNotify(ref _isCheckingForUpdates, value);
}
}
private bool _autoDownloadUpdatePackage = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AutoDownloadUpdatePackage, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to auto download update package.
/// </summary>
public bool AutoDownloadUpdatePackage
{
get => _autoDownloadUpdatePackage;
set
{
SetAndNotify(ref _autoDownloadUpdatePackage, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AutoDownloadUpdatePackage, value.ToString());
}
}
private bool _autoInstallUpdatePackage = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AutoInstallUpdatePackage, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to auto install update package.
/// </summary>
public bool AutoInstallUpdatePackage
{
get => _autoInstallUpdatePackage;
set
{
SetAndNotify(ref _autoInstallUpdatePackage, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AutoInstallUpdatePackage, value.ToString());
}
}
/// <summary>
/// Updates manually.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task ManualUpdate()
{
var ret = await Instances.VersionUpdateViewModel.CheckAndDownloadUpdate();
string toastMessage = null;
switch (ret)
{
case VersionUpdateViewModel.CheckUpdateRetT.NoNeedToUpdate:
break;
case VersionUpdateViewModel.CheckUpdateRetT.AlreadyLatest:
toastMessage = LocalizationHelper.GetString("AlreadyLatest");
break;
case VersionUpdateViewModel.CheckUpdateRetT.UnknownError:
toastMessage = LocalizationHelper.GetString("NewVersionDetectFailedTitle");
break;
case VersionUpdateViewModel.CheckUpdateRetT.NetworkError:
toastMessage = LocalizationHelper.GetString("CheckNetworking");
break;
case VersionUpdateViewModel.CheckUpdateRetT.FailedToGetInfo:
toastMessage = LocalizationHelper.GetString("GetReleaseNoteFailed");
break;
case VersionUpdateViewModel.CheckUpdateRetT.OK:
Instances.VersionUpdateViewModel.AskToRestart();
break;
case VersionUpdateViewModel.CheckUpdateRetT.NewVersionIsBeingBuilt:
toastMessage = LocalizationHelper.GetString("NewVersionIsBeingBuilt");
break;
case VersionUpdateViewModel.CheckUpdateRetT.OnlyGameReourceUpdated:
toastMessage = LocalizationHelper.GetString("GameResourceUpdated");
break;
}
if (toastMessage != null)
{
Execute.OnUIThread(() =>
{
using var toast = new ToastNotification(toastMessage);
toast.Show();
});
}
}
public void ShowChangelog()
{
Instances.WindowManager.ShowWindow(Instances.VersionUpdateViewModel);
}
/* 连接设置 */
private bool _autoDetectConnection = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.AutoDetect, true.ToString()));
public bool AutoDetectConnection
{
get => _autoDetectConnection;
set
{
SetAndNotify(ref _autoDetectConnection, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AutoDetect, value.ToString());
}
}
private bool _alwaysAutoDetectConnection = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.AlwaysAutoDetect, false.ToString()));
public bool AlwaysAutoDetectConnection
{
get => _alwaysAutoDetectConnection;
set
{
SetAndNotify(ref _alwaysAutoDetectConnection, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AlwaysAutoDetect, value.ToString());
}
}
private ObservableCollection<string> _connectAddressHistory = new ObservableCollection<string>();
public ObservableCollection<string> ConnectAddressHistory
{
get => _connectAddressHistory;
set => SetAndNotify(ref _connectAddressHistory, value);
}
private string _connectAddress = ConfigurationHelper.GetValue(ConfigurationKeys.ConnectAddress, string.Empty);
/// <summary>
/// Gets or sets the connection address.
/// </summary>
public string ConnectAddress
{
get => _connectAddress;
set
{
if (ConnectAddress == value || string.IsNullOrEmpty(value))
{
return;
}
UpdateConnectionHistory(value);
SetAndNotify(ref _connectAddress, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AddressHistory, JsonConvert.SerializeObject(ConnectAddressHistory));
ConfigurationHelper.SetValue(ConfigurationKeys.ConnectAddress, value);
UpdateWindowTitle(); /* 每次修改连接地址时更新WindowTitle */
}
}
private void UpdateConnectionHistory(string address)
{
var history = ConnectAddressHistory.ToList();
if (history.Contains(address))
{
history.Remove(address);
history.Insert(0, address);
}
else
{
history.Insert(0, address);
const int MaxHistoryCount = 5;
if (history.Count > MaxHistoryCount)
{
history.RemoveRange(MaxHistoryCount, history.Count - MaxHistoryCount);
}
}
ConnectAddressHistory = new ObservableCollection<string>(history);
}
public void RemoveAddress_Click(string address)
{
ConnectAddressHistory.Remove(address);
ConfigurationHelper.SetValue(ConfigurationKeys.AddressHistory, JsonConvert.SerializeObject(ConnectAddressHistory));
}
private string _adbPath = ConfigurationHelper.GetValue(ConfigurationKeys.AdbPath, string.Empty);
/// <summary>
/// Gets or sets the ADB path.
/// </summary>
public string AdbPath
{
get => _adbPath;
set
{
SetAndNotify(ref _adbPath, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AdbPath, value);
}
}
private string _connectConfig = ConfigurationHelper.GetValue(ConfigurationKeys.ConnectConfig, "General");
/// <summary>
/// Gets or sets the connection config.
/// </summary>
public string ConnectConfig
{
get => _connectConfig;
set
{
SetAndNotify(ref _connectConfig, value);
ConfigurationHelper.SetValue(ConfigurationKeys.ConnectConfig, value);
UpdateWindowTitle(); /* 每次修改连接配置时更新WindowTitle */
}
}
private bool _retryOnDisconnected = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.RetryOnAdbDisconnected, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to retry task after ADB disconnected.
/// </summary>
public bool RetryOnDisconnected
{
get => _retryOnDisconnected;
set
{
SetAndNotify(ref _retryOnDisconnected, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RetryOnAdbDisconnected, value.ToString());
}
}
private bool _allowAdbRestart = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AllowAdbRestart, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to retry task after ADB disconnected.
/// </summary>
public bool AllowAdbRestart
{
get => _allowAdbRestart;
set
{
SetAndNotify(ref _allowAdbRestart, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AllowAdbRestart, value.ToString());
}
}
private bool _allowAdbHardRestart = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AllowAdbHardRestart, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to allow for killing ADB process.
/// </summary>
public bool AllowAdbHardRestart
{
get => _allowAdbHardRestart;
set
{
SetAndNotify(ref _allowAdbHardRestart, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AllowAdbHardRestart, value.ToString());
}
}
private bool _deploymentWithPause = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.RoguelikeDeploymentWithPause, false.ToString()));
public bool DeploymentWithPause
{
get => _deploymentWithPause;
set
{
SetAndNotify(ref _deploymentWithPause, value);
ConfigurationHelper.SetValue(ConfigurationKeys.RoguelikeDeploymentWithPause, value.ToString());
UpdateInstanceSettings();
}
}
private bool _adbLiteEnabled = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.AdbLiteEnabled, false.ToString()));
public bool AdbLiteEnabled
{
get => _adbLiteEnabled;
set
{
SetAndNotify(ref _adbLiteEnabled, value);
ConfigurationHelper.SetValue(ConfigurationKeys.AdbLiteEnabled, value.ToString());
UpdateInstanceSettings();
}
}
private bool _killAdbOnExit = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.KillAdbOnExit, false.ToString()));
public bool KillAdbOnExit
{
get => _killAdbOnExit;
set
{
SetAndNotify(ref _killAdbOnExit, value);
ConfigurationHelper.SetValue(ConfigurationKeys.KillAdbOnExit, value.ToString());
UpdateInstanceSettings();
}
}
/// <summary>
/// Gets the default addresses.
/// </summary>
public Dictionary<string, List<string>> DefaultAddress { get; } = new Dictionary<string, List<string>>
{
{ "General", new List<string> { string.Empty } },
{ "BlueStacks", new List<string> { "127.0.0.1:5555", "127.0.0.1:5556", "127.0.0.1:5565", "127.0.0.1:5575", "127.0.0.1:5585", "127.0.0.1:5595", "127.0.0.1:5554" } },
{ "MuMuEmulator", new List<string> { "127.0.0.1:7555" } },
{ "MuMuEmulator12", new List<string> { "127.0.0.1:16384", "127.0.0.1:16416", "127.0.0.1:16448", "127.0.0.1:16480", "127.0.0.1:16512", "127.0.0.1:16544", "127.0.0.1:16576" } },
{ "LDPlayer", new List<string> { "emulator-5554", "emulator-5556", "emulator-5558", "emulator-5560", "127.0.0.1:5555", "127.0.0.1:5556", "127.0.0.1:5554" } },
{ "Nox", new List<string> { "127.0.0.1:62001", "127.0.0.1:59865" } },
{ "XYAZ", new List<string> { "127.0.0.1:21503" } },
{ "WSA", new List<string> { "127.0.0.1:58526" } },
};
/// <summary>
/// RegisterKey of Bluestacks_Nxt
/// </summary>
private const string BluestacksNxtRegistryKey = @"SOFTWARE\BlueStacks_nxt";
private const string BluestacksNxtValueName = "UserDefinedDir";
/// <summary>
/// Refreshes ADB config.
/// </summary>
/// <param name="error">Errors when doing this operation.</param>
/// <returns>Whether the operation is successful.</returns>
public bool DetectAdbConfig(ref string error)
{
var adapter = new WinAdapter();
List<string> emulators;
try
{
emulators = adapter.RefreshEmulatorsInfo();
}
catch (Exception e)
{
_logger.Information(e.Message);
error = LocalizationHelper.GetString("EmulatorException");
return false;
}
if (emulators.Count == 0)
{
error = LocalizationHelper.GetString("EmulatorNotFound");
return false;
}
else if (emulators.Count > 1)
{
error = LocalizationHelper.GetString("EmulatorTooMany");
return false;
}
ConnectConfig = emulators.First();
AdbPath = adapter.GetAdbPathByEmulatorName(ConnectConfig) ?? AdbPath;
if (string.IsNullOrEmpty(AdbPath))
{
error = LocalizationHelper.GetString("AdbException");
return false;
}
var addresses = adapter.GetAdbAddresses(AdbPath);
if (addresses.Count == 1)
{
ConnectAddress = addresses.First();
}
else if (addresses.Count > 1)
{
foreach (var address in addresses)
{
if (address == "emulator-5554")
{
continue;
}
ConnectAddress = address;
break;
}
}
if (ConnectAddress.Length == 0)
{
ConnectAddress = DefaultAddress[ConnectConfig][0];
}
return true;
}
/// <summary>
/// Get the path of bluestacks.conf
/// </summary>
/// <returns>path</returns>
private static string GetBluestacksConfig()
{
var conf = ConfigurationHelper.GetValue(ConfigurationKeys.BluestacksConfigPath, string.Empty);
if (!string.IsNullOrEmpty(conf))
{
return conf;
}
using RegistryKey key = Registry.LocalMachine.OpenSubKey(BluestacksNxtRegistryKey);
object value = key?.GetValue(BluestacksNxtValueName);
if (value != null)
{
return (string)value + "\\bluestacks.conf";
}
return null;
}
/// <summary>
/// Selects ADB program file.
/// </summary>
public void SelectFile()
{
var dialog = new OpenFileDialog
{
Filter = LocalizationHelper.GetString("AdbProgram") + "|*.exe",
};
if (dialog.ShowDialog() == true)
{
AdbPath = dialog.FileName;
}
}
/// <summary>
/// 标题栏显示模拟器名称和IP端口。
/// </summary>
public void UpdateWindowTitle()
{
var rvm = (RootViewModel)this.Parent;
var connectConfigName = string.Empty;
foreach (var data in ConnectConfigList)
{
if (data.Value == ConnectConfig)
{
connectConfigName = data.Display;
}
}
string prefix = ConfigurationHelper.GetValue(ConfigurationKeys.WindowTitlePrefix, string.Empty);
if (!string.IsNullOrEmpty(prefix))
{
prefix += " - ";
}
string officialClientType = "Official";
string bilibiliClientType = "Bilibili";
string jsonPath = "resource/version.json";
if (!(ClientType == string.Empty || ClientType == officialClientType || ClientType == bilibiliClientType))
{
jsonPath = $"resource/global/{ClientType}/resource/version.json";
}
string versionName = string.Empty;
if (File.Exists(jsonPath))
{
JObject versionJson = (JObject)JsonConvert.DeserializeObject(File.ReadAllText(jsonPath));
var currentTime = (ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var poolTime = (ulong)versionJson?["gacha"]["time"];
var activityTime = (ulong)versionJson?["activity"]["time"];
if ((currentTime < poolTime) && (currentTime < activityTime))
{
versionName = string.Empty;
}
else if ((currentTime >= poolTime) && (currentTime < activityTime))
{
versionName = versionJson?["gacha"]?["pool"]?.ToString() ?? string.Empty;
}
else if ((currentTime < poolTime) && (currentTime >= activityTime))
{
versionName = versionJson?["activity"]?["name"]?.ToString() ?? string.Empty;
}
else if (poolTime > activityTime)
{
versionName = versionJson?["gacha"]?["pool"]?.ToString() ?? string.Empty;
}
else
{
versionName = versionJson?["activity"]?["name"]?.ToString() ?? string.Empty;
}
}
string poolString = !string.IsNullOrEmpty(versionName) ? $" - {versionName}" : string.Empty;
rvm.WindowTitle = $"{prefix}MAA ({CurrentConfiguration}) - {VersionId}{poolString} - {connectConfigName} ({ConnectAddress}) - {ClientName}";
}
private readonly string _bluestacksConfig = GetBluestacksConfig();
private string _bluestacksKeyWord = ConfigurationHelper.GetValue(ConfigurationKeys.BluestacksConfigKeyword, string.Empty);
/// <summary>
/// Tries to set Bluestack Hyper V address.
/// </summary>
/// <returns>success</returns>
public string TryToSetBlueStacksHyperVAddress()
{
if (string.IsNullOrEmpty(_bluestacksConfig))
{
return null;
}
if (!File.Exists(_bluestacksConfig))
{
ConfigurationHelper.SetValue(ConfigurationKeys.BluestacksConfigError, "File not exists");
return null;
}
var allLines = File.ReadAllLines(_bluestacksConfig);
if (string.IsNullOrEmpty(_bluestacksKeyWord))
{
foreach (var line in allLines)
{
if (line.StartsWith("bst.installed_images"))
{
var images = line.Split('"')[1].Split(',');
_bluestacksKeyWord = "bst.instance." + images[0] + ".status.adb_port";
break;
}
}
}
foreach (var line in allLines)
{
if (line.StartsWith(_bluestacksKeyWord))
{
var sp = line.Split('"');
return "127.0.0.1:" + sp[1];
}
}
return null;
}
public bool IsAdbTouchMode()
{
return TouchMode == "adb";
}
private string _touchMode = ConfigurationHelper.GetValue(ConfigurationKeys.TouchMode, "minitouch");
public string TouchMode
{
get => _touchMode;
set
{
SetAndNotify(ref _touchMode, value);
ConfigurationHelper.SetValue(ConfigurationKeys.TouchMode, value);
UpdateInstanceSettings();
}
}
public void UpdateInstanceSettings()
{
Instances.AsstProxy.AsstSetInstanceOption(InstanceOptionKey.TouchMode, TouchMode);
Instances.AsstProxy.AsstSetInstanceOption(InstanceOptionKey.DeploymentWithPause, DeploymentWithPause ? "1" : "0");
Instances.AsstProxy.AsstSetInstanceOption(InstanceOptionKey.AdbLiteEnabled, AdbLiteEnabled ? "1" : "0");
Instances.AsstProxy.AsstSetInstanceOption(InstanceOptionKey.KillAdbOnExit, KillAdbOnExit ? "1" : "0");
}
private const string GoogleAdbDownloadUrl = "https://dl.google.com/android/repository/platform-tools-latest-windows.zip";
private const string AdbMaaMirrorDownloadUrl = "https://ota.maa.plus/MaaAssistantArknights/api/binaries/adb-windows.zip";
private const string GoogleAdbFilename = "adb-windows.zip";
// UI 绑定的方法
// ReSharper disable once UnusedMember.Global
public async void ReplaceAdb()
{
if (string.IsNullOrEmpty(AdbPath))
{
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("NoAdbPathSpecifiedMessage"));
toast.Show();
});
return;
}
if (!File.Exists(GoogleAdbFilename))
{
var downloadResult = await Instances.HttpService.DownloadFileAsync(new Uri(GoogleAdbDownloadUrl), GoogleAdbFilename);
if (!downloadResult)
{
downloadResult = await Instances.HttpService.DownloadFileAsync(new Uri(AdbMaaMirrorDownloadUrl), GoogleAdbFilename);
}
if (!downloadResult)
{
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("AdbDownloadFailedTitle"));
toast.AppendContentText(LocalizationHelper.GetString("AdbDownloadFailedDesc")).Show();
});
return;
}
}
const string UnzipDir = "adb";
const string NewAdb = UnzipDir + "/platform-tools/adb.exe";
try
{
if (Directory.Exists(UnzipDir))
{
Directory.Delete(UnzipDir, true);
}
}
catch (Exception ex)
{
_logger.Error($"An error occurred while deleting directory: {ex.GetType()}: {ex.Message}");
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("AdbDeletionFailedMessage"));
toast.Show();
});
return;
}
try
{
ZipFile.ExtractToDirectory(GoogleAdbFilename, UnzipDir);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("UnzipFailedMessage"));
toast.Show();
});
return;
}
bool replaced = false;
if (AdbPath != NewAdb && File.Exists(AdbPath))
{
try
{
foreach (var process in Process.GetProcessesByName(Path.GetFileName(AdbPath)))
{
process.Kill();
process.WaitForExit(5000);
}
string adbBack = AdbPath + ".bak";
if (!File.Exists(adbBack))
{
File.Copy(AdbPath, adbBack, true);
}
File.Copy(NewAdb, AdbPath, true);
replaced = true;
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
replaced = false;
}
}
if (replaced)
{
AdbReplaced = true;
ConfigurationHelper.SetValue(ConfigurationKeys.AdbReplaced, true.ToString());
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("SuccessfullyReplacedAdb"));
toast.Show();
});
}
else
{
AdbPath = NewAdb;
_ = Execute.OnUIThreadAsync(() =>
{
using var toast = new ToastNotification(LocalizationHelper.GetString("FailedToReplaceAdbAndUseLocal"));
toast.AppendContentText(LocalizationHelper.GetString("FailedToReplaceAdbAndUseLocalDesc")).Show();
});
}
}
public bool AdbReplaced { get; set; } = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.AdbReplaced, false.ToString()));
/* 界面设置 */
/// <summary>
/// Gets a value indicating whether to use tray icon.
/// </summary>
public bool UseTray => true;
private bool _minimizeToTray = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.MinimizeToTray, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to minimize to tray.
/// </summary>
public bool MinimizeToTray
{
get => _minimizeToTray;
set
{
SetAndNotify(ref _minimizeToTray, value);
ConfigurationHelper.SetValue(ConfigurationKeys.MinimizeToTray, value.ToString());
Instances.MainWindowManager.SetMinimizeToTaskbar(value);
}
}
private bool _hideCloseButton = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.HideCloseButton, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to hide close button.
/// </summary>
public bool HideCloseButton
{
get => _hideCloseButton;
set
{
SetAndNotify(ref _hideCloseButton, value);
ConfigurationHelper.SetValue(ConfigurationKeys.HideCloseButton, value.ToString());
var rvm = (RootViewModel)this.Parent;
rvm.ShowCloseButton = !value;
}
}
/// <summary>
/// Gets or sets a value indicating whether to use notification.
/// </summary>
public bool UseNotify
{
get => ConfigFactory.CurrentConfig.GuiConfig.UseNotify;
set
{
ConfigFactory.CurrentConfig.GuiConfig.UseNotify = value;
NotifyOfPropertyChange();
if (value)
{
Execute.OnUIThread(() =>
{
using var toast = new ToastNotification("Test test");
toast.Show();
});
}
}
}
private bool _useLogItemDateFormat = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.UseLogItemDateFormat, bool.FalseString));
public bool UseLogItemDateFormat
{
get => _useLogItemDateFormat;
set
{
SetAndNotify(ref _useLogItemDateFormat, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UseLogItemDateFormat, value.ToString());
}
}
public List<string> LogItemDateFormatStringList { get; } = new List<string>
{
"HH:mm:ss",
"MM-dd HH:mm:ss",
"MM/dd HH:mm:ss",
"MM.dd HH:mm:ss",
"dd-MM HH:mm:ss",
"dd/MM HH:mm:ss",
"dd.MM HH:mm:ss",
};
private string _logItemDateFormatString = ConfigurationHelper.GetValue(ConfigurationKeys.LogItemDateFormat, "HH:mm:ss");
public string LogItemDateFormatString
{
get => _logItemDateFormatString;
set
{
SetAndNotify(ref _logItemDateFormatString, value);
ConfigurationHelper.SetValue(ConfigurationKeys.LogItemDateFormat, value);
}
}
private bool _useAlternateStage = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.UseAlternateStage, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to use alternate stage.
/// </summary>
public bool UseAlternateStage
{
get => _useAlternateStage;
set
{
SetAndNotify(ref _useAlternateStage, value);
Instances.TaskQueueViewModel.UseAlternateStage = value;
ConfigurationHelper.SetValue(ConfigurationKeys.UseAlternateStage, value.ToString());
if (value)
{
HideUnavailableStage = false;
}
}
}
private bool _useRemainingSanityStage = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.UseRemainingSanityStage, bool.TrueString));
public bool UseRemainingSanityStage
{
get => _useRemainingSanityStage;
set
{
SetAndNotify(ref _useRemainingSanityStage, value);
Instances.TaskQueueViewModel.UseRemainingSanityStage = value;
ConfigurationHelper.SetValue(ConfigurationKeys.UseRemainingSanityStage, value.ToString());
}
}
private bool _useExpiringMedicine = bool.Parse(ConfigurationHelper.GetValue(ConfigurationKeys.UseExpiringMedicine, bool.FalseString));
public bool UseExpiringMedicine
{
get => _useExpiringMedicine;
set
{
SetAndNotify(ref _useExpiringMedicine, value);
ConfigurationHelper.SetValue(ConfigurationKeys.UseExpiringMedicine, value.ToString());
}
}
private bool _hideUnavailableStage = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.HideUnavailableStage, bool.TrueString));
/// <summary>
/// Gets or sets a value indicating whether to hide unavailable stages.
/// </summary>
public bool HideUnavailableStage
{
get => _hideUnavailableStage;
set
{
SetAndNotify(ref _hideUnavailableStage, value);
ConfigurationHelper.SetValue(ConfigurationKeys.HideUnavailableStage, value.ToString());
if (value)
{
UseAlternateStage = false;
}
Instances.TaskQueueViewModel.UpdateStageList(true);
}
}
private bool _customStageCode = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.CustomStageCode, bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to use custom stage code.
/// </summary>
public bool CustomStageCode
{
get => _customStageCode;
set
{
SetAndNotify(ref _customStageCode, value);
ConfigurationHelper.SetValue(ConfigurationKeys.CustomStageCode, value.ToString());
Instances.TaskQueueViewModel.CustomStageCode = value;
}
}
/// <summary>
/// Gets or sets the dark mode.
/// </summary>
public string DarkMode
{
get => ConfigFactory.CurrentConfig.GuiConfig.DarkMode.ToString();
set
{
if (!Enum.TryParse(value, out DarkModeType tempEnumValue))
{
return;
}
ConfigFactory.CurrentConfig.GuiConfig.DarkMode = tempEnumValue;
NotifyOfPropertyChange();
SwitchDarkMode();
/*
var result = MessageBoxHelper.Show(
LocalizationHelper.GetString("DarkModeSetColorsTip"),
LocalizationHelper.GetString("Tip"),
MessageBoxButton.OKCancel,
MessageBoxImage.Question);
if (result == MessageBoxResult.OK)
{
Bootstrapper.ShutdownAndRestartWithOutArgs();
}
*/
}
}
public void SwitchDarkMode()
{
DarkModeType darkModeType = ConfigFactory.CurrentConfig.GuiConfig.DarkMode;
switch (darkModeType)
{
case DarkModeType.Light:
ThemeHelper.SwitchToLightMode();
break;
case DarkModeType.Dark:
ThemeHelper.SwitchToDarkMode();
break;
case DarkModeType.SyncWithOS:
ThemeHelper.SwitchToSyncWithOsMode();
break;
}
}
private enum InverseClearType
{
Clear,
Inverse,
ClearInverse,
}
private InverseClearType _inverseClearMode =
Enum.TryParse(ConfigurationHelper.GetValue(ConfigurationKeys.InverseClearMode, InverseClearType.Clear.ToString()),
out InverseClearType temp)
? temp : InverseClearType.Clear;
/// <summary>
/// Gets or sets the inverse clear mode.
/// </summary>
public string InverseClearMode
{
get => _inverseClearMode.ToString();
set
{
if (!Enum.TryParse(value, out InverseClearType tempEnumValue))
{
return;
}
SetAndNotify(ref _inverseClearMode, tempEnumValue);
ConfigurationHelper.SetValue(ConfigurationKeys.InverseClearMode, value);
switch (tempEnumValue)
{
case InverseClearType.Clear:
Instances.TaskQueueViewModel.InverseMode = false;
Instances.TaskQueueViewModel.ShowInverse = false;
Instances.TaskQueueViewModel.SelectedAllWidth = 90;
break;
case InverseClearType.Inverse:
Instances.TaskQueueViewModel.InverseMode = true;
Instances.TaskQueueViewModel.ShowInverse = false;
Instances.TaskQueueViewModel.SelectedAllWidth = 90;
break;
case InverseClearType.ClearInverse:
Instances.TaskQueueViewModel.ShowInverse = true;
Instances.TaskQueueViewModel.SelectedAllWidth = TaskQueueViewModel.SelectedAllWidthWhenBoth;
break;
}
}
}
private string _soberLanguage = ConfigurationHelper.GetValue("GUI.SoberLanguage", LocalizationHelper.DefaultLanguage);
public string SoberLanguage
{
get => _soberLanguage;
set
{
SetAndNotify(ref _soberLanguage, value);
ConfigurationHelper.SetValue("GUI.SoberLanguage", value);
}
}
private string _language = ConfigurationHelper.GetValue(ConfigurationKeys.Localization, LocalizationHelper.DefaultLanguage);
/// <summary>
/// Gets or sets the language.
/// </summary>
public string Language
{
get => _language;
set
{
if (value == _language)
{
return;
}
if (_language == PallasLangKey)
{
Hangover = true;
Cheers = false;
}
if (value != PallasLangKey)
{
SoberLanguage = value;
}
// var backup = _language;
ConfigurationHelper.SetValue(ConfigurationKeys.Localization, value);
string FormatText(string text, string key)
=> string.Format(text, LocalizationHelper.GetString(key, value), LocalizationHelper.GetString(key, _language));
var mainWindow = Application.Current.MainWindow;
mainWindow.Show();
mainWindow.WindowState = mainWindow.WindowState = WindowState.Normal;
mainWindow.Activate();
var result = MessageBoxHelper.Show(
FormatText("{0}\n{1}", "LanguageChangedTip"),
FormatText("{0}({1})", "Tip"),
MessageBoxButton.OKCancel,
MessageBoxImage.Question,
ok: FormatText("{0}({1})", "Ok"),
cancel: FormatText("{0}({1})", "ManualRestart"));
if (result == MessageBoxResult.OK)
{
Bootstrapper.ShutdownAndRestartWithOutArgs();
}
SetAndNotify(ref _language, value);
}
}
/// <summary>
/// Gets the language info.
/// </summary>
public string LanguageInfo
{
get
{
var language = (string)Application.Current.Resources["Language"];
return language == "Language" ? language : language + " / Language";
}
}
private bool _cheers = bool.Parse(ConfigurationHelper.GetValue("GUI.Cheers", bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to cheer.
/// </summary>
public bool Cheers
{
get => _cheers;
set
{
if (_cheers == value)
{
return;
}
SetAndNotify(ref _cheers, value);
ConfigurationHelper.SetValue("GUI.Cheers", value.ToString());
if (_cheers)
{
SetPallasLanguage();
}
}
}
private bool _hangover = bool.Parse(ConfigurationHelper.GetValue("GUI.Hangover", bool.FalseString));
/// <summary>
/// Gets or sets a value indicating whether to hangover.
/// </summary>
public bool Hangover
{
get => _hangover;
set
{
SetAndNotify(ref _hangover, value);
ConfigurationHelper.SetValue("GUI.Hangover", value.ToString());
}
}
private void SetPallasLanguage()
{
ConfigurationHelper.SetValue(ConfigurationKeys.Localization, PallasLangKey);
var result = MessageBoxHelper.Show(
LocalizationHelper.GetString("DrunkAndStaggering"),
LocalizationHelper.GetString("Burping"),
MessageBoxButton.OK,
iconKey: "DrunkAndStaggeringGeometry",
iconBrushKey: "PallasBrush");
if (result == MessageBoxResult.OK)
{
Bootstrapper.ShutdownAndRestartWithOutArgs();
}
}
/// <summary>
/// Gets or sets the hotkey: ShowGui.
/// </summary>
public MaaHotKey HotKeyShowGui
{
get => Instances.MaaHotKeyManager.GetOrNull(MaaHotKeyAction.ShowGui);
set => SetHotKey(MaaHotKeyAction.ShowGui, value);
}
/// <summary>
/// Gets or sets the hotkey: LinkStart.
/// </summary>
public MaaHotKey HotKeyLinkStart
{
get => Instances.MaaHotKeyManager.GetOrNull(MaaHotKeyAction.LinkStart);
set => SetHotKey(MaaHotKeyAction.LinkStart, value);
}
private void SetHotKey(MaaHotKeyAction action, MaaHotKey value)
{
if (value != null)
{
Instances.MaaHotKeyManager.TryRegister(action, value);
}
else
{
Instances.MaaHotKeyManager.Unregister(action);
}
}
/// <summary>
/// Did you buy wine?
/// </summary>
/// <returns>The answer.</returns>
public bool DidYouBuyWine()
{
if (DateTime.UtcNow.ToYjDate().IsAprilFoolsDay())
{
return true;
}
var wineList = new[] { "酒", "liquor", "drink", "wine", "beer", "술", "🍷", "🍸", "🍺", "🍻", "🥃", "🍶" };
return wineList.Any(wine => CreditFirstList.Contains(wine));
}
private void UpdateRoguelikeSquadList()
{
var roguelikeSquad = RoguelikeSquad;
RoguelikeSquadList = new ObservableCollection<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("DefaultSquad"), Value = string.Empty },
};
switch (RoguelikeTheme)
{
case "Phantom":
foreach (var item in new ObservableCollection<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("ResearchSquad"), Value = "研究分队" },
})
{
RoguelikeSquadList.Add(item);
}
break;
case "Mizuki":
foreach (var item in new ObservableCollection<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("IS2NewSquad1"), Value = "心胜于物分队" },
new CombinedData { Display = LocalizationHelper.GetString("IS2NewSquad2"), Value = "物尽其用分队" },
new CombinedData { Display = LocalizationHelper.GetString("IS2NewSquad3"), Value = "以人为本分队" },
new CombinedData { Display = LocalizationHelper.GetString("ResearchSquad"), Value = "研究分队" },
})
{
RoguelikeSquadList.Add(item);
}
break;
case "Sami":
foreach (var item in new ObservableCollection<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("IS3NewSquad1"), Value = "永恒狩猎分队" },
new CombinedData { Display = LocalizationHelper.GetString("IS3NewSquad2"), Value = "生活至上分队" },
new CombinedData { Display = LocalizationHelper.GetString("IS3NewSquad3"), Value = "科学主义分队" },
new CombinedData { Display = LocalizationHelper.GetString("IS3NewSquad4"), Value = "特训分队" },
})
{
RoguelikeSquadList.Add(item);
}
break;
}
// 通用分队
foreach (var item in new ObservableCollection<CombinedData>
{
new CombinedData { Display = LocalizationHelper.GetString("LeaderSquad"), Value = "指挥分队" },
new CombinedData { Display = LocalizationHelper.GetString("GatheringSquad"), Value = "集群分队" },
new CombinedData { Display = LocalizationHelper.GetString("SupportSquad"), Value = "后勤分队" },
new CombinedData { Display = LocalizationHelper.GetString("SpearheadSquad"), Value = "矛头分队" },
new CombinedData { Display = LocalizationHelper.GetString("TacticalAssaultOperative"), Value = "突击战术分队" },
new CombinedData { Display = LocalizationHelper.GetString("TacticalFortificationOperative"), Value = "堡垒战术分队" },
new CombinedData { Display = LocalizationHelper.GetString("TacticalRangedOperative"), Value = "远程战术分队" },
new CombinedData { Display = LocalizationHelper.GetString("TacticalDestructionOperative"), Value = "破坏战术分队" },
new CombinedData { Display = LocalizationHelper.GetString("First-ClassSquad"), Value = "高规格分队" },
})
{
RoguelikeSquadList.Add(item);
}
_roguelikeSquad = RoguelikeSquadList.Any(x => x.Value == roguelikeSquad) ? roguelikeSquad : string.Empty;
}
private void UpdateRoguelikeCoreCharList()
{
var filePath = $"resource/roguelike/{RoguelikeTheme}/recruitment.json";
if (File.Exists(filePath) is false)
{
RoguelikeCoreCharList.Clear();
return;
}
var jsonStr = File.ReadAllText(filePath);
var json = (JObject)JsonConvert.DeserializeObject(jsonStr);
var roguelikeCoreCharList = new ObservableCollection<string>();
if (json?["priority"] is JArray priorityArray)
{
foreach (var priorityItem in priorityArray)
{
if (!(priorityItem?["opers"] is JArray opersArray))
{
continue;
}
foreach (var operItem in opersArray)
{
var isStart = (bool?)operItem.SelectToken("is_start") ?? false;
if (!isStart)
{
continue;
}
var name = (string)operItem.SelectToken("name");
if (!string.IsNullOrEmpty(name))
{
roguelikeCoreCharList.Add(name);
}
}
}
}
RoguelikeCoreCharList = roguelikeCoreCharList;
}
#region SettingsGuide
// 目前共4步再多塞不下了后续可以整个新功能展示
public const int GuideMaxStep = 4;
private int _guideStepIndex = Convert.ToInt32(ConfigurationHelper.GetValue(ConfigurationKeys.GuideStepIndex, "0"));
public int GuideStepIndex
{
get => _guideStepIndex;
set
{
SetAndNotify(ref _guideStepIndex, value);
if (value == GuideMaxStep)
{
ConfigurationHelper.SetValue(ConfigurationKeys.GuideStepIndex, value.ToString());
}
}
}
private string _guideTransitionMode = "Bottom2Top";
public string GuideTransitionMode
{
get => _guideTransitionMode;
set => SetAndNotify(ref _guideTransitionMode, value);
}
public void NextGuide(HandyControl.Controls.StepBar stepBar)
{
GuideTransitionMode = "Bottom2Top";
stepBar.Next();
}
public void PrevGuide(HandyControl.Controls.StepBar stepBar)
{
GuideTransitionMode = "Top2Bottom";
stepBar.Prev();
}
public void DoneGuide()
{
TaskSettingVisibilities.Guide = false;
GuideStepIndex = GuideMaxStep;
}
#endregion SettingsGuide
/// <summary>
/// Make comboBox searchable
/// </summary>
/// <param name="sender">Event sender</param>
/// <param name="e">Event args</param>
// UI 绑定的方法
// EventArgs 不能省略,否则会报错
// ReSharper disable once UnusedMember.Global
// ReSharper disable once UnusedParameter.Global
public void MakeComboBoxSearchable(object sender, EventArgs e)
{
(sender as ComboBox)?.MakeComboBoxSearchable();
}
// UI 绑定的方法
// ReSharper disable once UnusedMember.Global
public async Task CheckAndDownloadAnnouncement()
{
await Instances.AnnouncementViewModel.CheckAndDownloadAnnouncement();
_ = Execute.OnUIThreadAsync(() => Instances.WindowManager.ShowWindow(Instances.AnnouncementViewModel));
}
}
}