feat: 添加GUI配置管理器

This commit is contained in:
MistEO
2023-05-26 18:03:02 +08:00
parent 1e2f69d79b
commit abaff85f22
8 changed files with 213 additions and 45 deletions

View File

@@ -18,6 +18,12 @@ namespace MaaWpfGui.Constants
/// </summary>
public static class ConfigurationKeys
{
public const string CurrentConfiguration = "Current";
public const string DefaultConfiguration = "Default";
public const string ConfigurationMap = "Configurations";
public const string ConfigurationData = "Data";
public const string ConfigurationCron = "Cron";
public const string Localization = "GUI.Localization";
public const string MinimizeToTray = "GUI.MinimizeToTray";
public const string HideCloseButton = "GUI.HideCloseButton";

View File

@@ -14,7 +14,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Linq;
using MaaWpfGui.Constants;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Serilog;
namespace MaaWpfGui.Helper
@@ -23,6 +26,8 @@ namespace MaaWpfGui.Helper
{
private static readonly string _configurationFile = Path.Combine(Environment.CurrentDirectory, "config/gui.json");
private static readonly string _configurationBakFile = Path.Combine(Environment.CurrentDirectory, "config/gui.json.bak");
private static Dictionary<string, Dictionary<string, string>> _kvsMap;
private static string _current = ConfigurationKeys.DefaultConfiguration;
private static Dictionary<string, string> _kvs;
private static readonly ILogger _logger = Log.ForContext<ConfigurationHelper>();
@@ -124,29 +129,6 @@ namespace MaaWpfGui.Helper
Directory.CreateDirectory("config");
}
// Config file migration
const string OldConfigFile = "gui.json";
if (File.Exists(OldConfigFile))
{
if (File.Exists(_configurationFile))
{
File.Delete(OldConfigFile);
}
File.Move(OldConfigFile, _configurationFile);
}
var oldBakFiles = Directory.GetFiles(".", "gui.json.bak*");
if (oldBakFiles.Length != 0)
{
_logger.Information("Found old backup files, deleting...");
foreach (var f in oldBakFiles)
{
File.Delete(f);
_logger.Information("Deleted {0}", f);
}
}
// Load configuration file
var parsed = ParseJsonFile(_configurationFile);
if (parsed is null)
@@ -161,15 +143,34 @@ namespace MaaWpfGui.Helper
if (parsed is null)
{
_logger.Information("Failed to load configuration file, creating a new one");
_kvs = new Dictionary<string, string>();
_kvsMap = new Dictionary<string, Dictionary<string, string>>();
_current = ConfigurationKeys.DefaultConfiguration;
_kvsMap[_current] = new Dictionary<string, string>();
_kvs = _kvsMap[_current];
return false;
}
if (parsed.ContainsKey(ConfigurationKeys.ConfigurationMap))
{
// new version
_kvsMap = parsed[ConfigurationKeys.ConfigurationMap].ToObject<Dictionary<string, Dictionary<string, string>>>();
_current = parsed[ConfigurationKeys.CurrentConfiguration].ToString();
_kvs = _kvsMap[_current];
}
else
{
_kvs = parsed;
return true;
// old version
_logger.Information("Configuration file is in old version, migrating to new version");
_kvsMap = new Dictionary<string, Dictionary<string, string>>();
_current = ConfigurationKeys.DefaultConfiguration;
_kvsMap[_current] = parsed.ToObject<Dictionary<string, string>>();
_kvs = _kvsMap[_current];
}
return false;
return true;
}
/// <summary>
@@ -184,10 +185,11 @@ namespace MaaWpfGui.Helper
return false;
}
var jsonStr = JsonSerializer.Serialize(_kvs, new JsonSerializerOptions
var jsonStr = JsonConvert.SerializeObject(new Dictionary<string, object>
{
WriteIndented = true,
});
{ ConfigurationKeys.ConfigurationMap, _kvsMap },
{ ConfigurationKeys.CurrentConfiguration, _current },
}, Formatting.Indented);
try
{
@@ -272,18 +274,18 @@ namespace MaaWpfGui.Helper
Released = true;
}
private static Dictionary<string, string> ParseJsonFile(string filePath)
private static JObject ParseJsonFile(string filePath)
{
if (File.Exists(filePath) is false)
{
return null;
}
var fs = File.OpenRead(filePath);
var str = File.ReadAllText(filePath);
try
{
var obj = JsonSerializer.Deserialize<Dictionary<string, string>>(fs);
var obj = (JObject)JsonConvert.DeserializeObject(str);
if (obj is null)
{
throw new Exception("Failed to parse json file");
@@ -295,12 +297,75 @@ namespace MaaWpfGui.Helper
{
_logger.Error(ex, "Failed to deserialize json file: {FilePath}", filePath);
}
finally
{
fs.Close();
}
return null;
}
public static bool SwitchConfiguration(string configName)
{
if (_kvsMap.ContainsKey(configName) is false)
{
_logger.Warning("Configuration {ConfigName} does not exist", configName);
return false;
}
_current = configName;
_kvs = _kvsMap[_current];
return true;
}
public static bool AddConfiguration(string configName, string copyFrom = null)
{
if (_kvsMap.ContainsKey(configName))
{
_logger.Warning("Configuration {ConfigName} already exists", configName);
return false;
}
if (copyFrom is null)
{
_kvsMap[configName] = new Dictionary<string, string>();
}
else
{
if (_kvsMap.ContainsKey(copyFrom) is false)
{
_logger.Warning("Configuration {ConfigName} does not exist", copyFrom);
return false;
}
_kvsMap[configName] = new Dictionary<string, string>(_kvsMap[copyFrom]);
}
return true;
}
public static bool DeleteConfiguration(string configName)
{
if (_kvsMap.ContainsKey(configName) is false)
{
_logger.Warning("Configuration {ConfigName} does not exist", configName);
return false;
}
if (_current == configName)
{
_logger.Warning("Configuration {ConfigName} is current configuration, cannot delete", configName);
return false;
}
_kvsMap.Remove(configName);
return true;
}
public static List<string> GetConfigurationList()
{
return _kvsMap.Keys.ToList();
}
public static string GetCurrentConfiguration()
{
return _current;
}
}
}

View File

@@ -197,6 +197,7 @@
<system:String x:Key="NewVersionFoundButNoPackageDesc">Please download the full package manually to update.</system:String>
<system:String x:Key="Timer">Timer</system:String>
<system:String x:Key="SwitchConfiguration">Switch Configuration</system:String>
<system:String x:Key="LaunchOnSystemStartup">Auto start with PC</system:String>
<system:String x:Key="RunTaskAfterLaunch">Auto Run task after launched</system:String>

View File

@@ -200,6 +200,8 @@
<system:String x:Key="Timer">定时</system:String>
<system:String x:Key="SwitchConfiguration">切换配置</system:String>
<system:String x:Key="LaunchOnSystemStartup">开机自动启动MAA</system:String>
<system:String x:Key="RunTaskAfterLaunch">启动MAA后直接运行</system:String>
<system:String x:Key="MinimizeAfterLaunch">启动MAA后直接最小化</system:String>

View File

@@ -93,6 +93,7 @@ namespace MaaWpfGui.ViewModels.UI
{
DisplayName = LocalizationHelper.GetString("Settings");
_listTitle.Add(LocalizationHelper.GetString("SwitchConfiguration"));
_listTitle.Add(LocalizationHelper.GetString("ScheduleSettings"));
_listTitle.Add(LocalizationHelper.GetString("GameSettings"));
_listTitle.Add(LocalizationHelper.GetString("ConnectionSettings"));
@@ -265,6 +266,14 @@ namespace MaaWpfGui.ViewModels.UI
new CombinedData { Display = LocalizationHelper.GetString("txwy"), Value = "txwy" },
};
var configurations = new List<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" },
@@ -851,6 +860,23 @@ namespace MaaWpfGui.ViewModels.UI
/// </summary>
public List<CombinedData> ClientTypeList { get; set; }
public List<CombinedData> ConfigurationList { get; set; }
private string _currentConfiguration = ConfigurationHelper.GetCurrentConfiguration();
public string CurrentConfiguration
{
get => _currentConfiguration;
set
{
SetAndNotify(ref _currentConfiguration, value);
ConfigurationHelper.SwitchConfiguration(value);
Application.Current.Shutdown();
Bootstrapper.RestartApplication();
}
}
/// <summary>
/// Gets or sets the list of the configuration of connection.
/// </summary>

View File

@@ -45,33 +45,36 @@
<StackPanel>
<hc:Divider Content="{Binding ListTitle[0]}" />
<userControl:TimerSettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<userControl:ConfigurationMgrUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[1]}" />
<userControl:TimerSettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[2]}" />
<userControl:GameClientUserControl
Margin="0,20"
HorizontalAlignment="Center"
IsEnabled="{Binding Idle}" />
<hc:Divider Content="{Binding ListTitle[2]}" />
<hc:Divider Content="{Binding ListTitle[3]}" />
<userControl:ConnectSettingsUserControl
Margin="0,20"
HorizontalAlignment="Center"
IsEnabled="{Binding Idle}" />
<hc:Divider Content="{Binding ListTitle[3]}" />
<hc:Divider Content="{Binding ListTitle[4]}" />
<userControl:StartSettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[4]}" />
<hc:Divider Content="{Binding ListTitle[5]}" />
<userControl:GUISettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[5]}" />
<hc:Divider Content="{Binding ListTitle[6]}" />
<userControl:HotKeySettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[6]}" />
<hc:Divider Content="{Binding ListTitle[7]}" />
<userControl:VersionUpdateSettingsUserControl Margin="0,20" HorizontalAlignment="Center" />
<hc:Divider Content="{Binding ListTitle[7]}" />
<hc:Divider Content="{Binding ListTitle[8]}" />
<userControl:AboutUserControl Margin="0,20" HorizontalAlignment="Center" />
<!--<Rectangle HorizontalAlignment="Stretch" Fill="{DynamicResource BorderBrush}" Height="1" />-->
</StackPanel>

View File

@@ -0,0 +1,36 @@
<UserControl
x:Class="MaaWpfGui.Views.UserControl.ConfigurationMgrUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
xmlns:constants="clr-namespace:MaaWpfGui.Constants"
xmlns:controls="clr-namespace:MaaWpfGui.Styles.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dd="urn:gong-wpf-dragdrop"
xmlns:helper="clr-namespace:MaaWpfGui.Helper"
xmlns:local="clr-namespace:MaaWpfGui"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:styles="clr-namespace:MaaWpfGui.Styles"
xmlns:ui="clr-namespace:MaaWpfGui.ViewModels.UI"
xmlns:viewModels="clr-namespace:MaaWpfGui.ViewModels"
xmlns:vm="clr-namespace:MaaWpfGui"
d:DataContext="{d:DesignInstance {x:Type ui:SettingsViewModel}}"
d:DesignWidth="550"
mc:Ignorable="d">
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<ComboBox
Width="200"
Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
DisplayMemberPath="Display"
IsHitTestVisible="{Binding Idle}"
ItemsSource="{Binding ConfigurationList}"
SelectedValue="{Binding CurrentConfiguration}"
SelectedValuePath="Value" />
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,29 @@
// <copyright file="GameClientUserControl.xaml.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>
namespace MaaWpfGui.Views.UserControl
{
/// <summary>
/// GameClientUserControl.xaml 的交互逻辑
/// </summary>
public partial class ConfigurationMgrUserControl : System.Windows.Controls.UserControl
{
/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationMgrUserControl"/> class.
/// </summary>
public ConfigurationMgrUserControl()
{
InitializeComponent();
}
}
}