diff --git a/VPet.Solution/Converters.xaml b/VPet.Solution/Converters.xaml index dae08b0..71ef646 100644 --- a/VPet.Solution/Converters.xaml +++ b/VPet.Solution/Converters.xaml @@ -8,6 +8,16 @@ + + + diff --git a/VPet.Solution/Converters/BoolInverter.cs b/VPet.Solution/Converters/BoolInverter.cs index 7ab221f..7033fbf 100644 --- a/VPet.Solution/Converters/BoolInverter.cs +++ b/VPet.Solution/Converters/BoolInverter.cs @@ -13,7 +13,7 @@ public class BoolInverter : ValueConverterBase public static readonly DependencyProperty NullValueProperty = DependencyProperty.Register( nameof(NullValue), typeof(bool), - typeof(AllIsBoolToVisibilityConverter), + typeof(BoolInverter), new PropertyMetadata(false) ); diff --git a/VPet.Solution/Converters/NullToVisibilityConverter.cs b/VPet.Solution/Converters/NullToVisibilityConverter.cs new file mode 100644 index 0000000..5b7ee71 --- /dev/null +++ b/VPet.Solution/Converters/NullToVisibilityConverter.cs @@ -0,0 +1,60 @@ +using System.ComponentModel; +using System.Globalization; +using System.Windows; + +namespace HKW.WPF.Converters; + +public class NullToVisibilityConverter : ValueConverterBase +{ + /// + /// + /// + public static readonly DependencyProperty NullVisibilityValueProperty = + DependencyProperty.Register( + nameof(NullVisibilityValue), + typeof(Visibility), + typeof(NullToVisibilityConverter), + new PropertyMetadata(Visibility.Hidden) + ); + + /// + /// NULL时的可见度 + /// + [DefaultValue(Visibility.Hidden)] + public Visibility NullVisibilityValue + { + get => (Visibility)GetValue(NullVisibilityValueProperty); + set => SetValue(NullVisibilityValueProperty, value); + } + + /// + /// + /// + public static readonly DependencyProperty NotNullVisibilityValueProperty = + DependencyProperty.Register( + nameof(NotNullVisibilityValue), + typeof(Visibility), + typeof(NullToVisibilityConverter), + new PropertyMetadata(Visibility.Visible) + ); + + /// + /// 不为NULL时的可见度 + /// + [DefaultValue(Visibility.Visible)] + public Visibility NotNullVisibilityValue + { + get => (Visibility)GetValue(NotNullVisibilityValueProperty); + set => SetValue(NotNullVisibilityValueProperty, value); + } + + public override object Convert( + object value, + Type targetType, + object parameter, + CultureInfo culture + ) + { + return value is null ? NullVisibilityValue : NotNullVisibilityValue; + } +} diff --git a/VPet.Solution/Models/ModLoader.cs b/VPet.Solution/Models/ModLoader.cs new file mode 100644 index 0000000..a14cda3 --- /dev/null +++ b/VPet.Solution/Models/ModLoader.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using LinePutScript; +using LinePutScript.Converter; +using LinePutScript.Dictionary; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using VPet_Simulator.Core; +using VPet_Simulator.Windows.Interface; +using System.Windows.Media.Imaging; + +namespace VPet.Solution.Models; + +/// +/// 模组加载器 +/// +public class ModLoader +{ + /// + /// 名称 + /// + public string Name { get; } + + /// + /// 作者 + /// + public string Author { get; } + + /// + /// 如果是上传至Steam,则为SteamUserID + /// + public long AuthorID { get; } + + /// + /// 上传至Steam的ItemID + /// + public ulong ItemID { get; } + + /// + /// 简介 + /// + public string Intro { get; } + + /// + /// 模组路径 + /// + public string ModPath { get; } + + /// + /// 支持的游戏版本 + /// + public int GameVer { get; } + + /// + /// 版本 + /// + public int Ver { get; } + + /// + /// 标签 + /// + public HashSet Tags { get; } = new(); + + /// + /// 缓存数据 + /// + public DateTime CacheDate { get; } = DateTime.MinValue; + + public BitmapImage? Image { get; } = null; + + public ModLoader(string path) + { + ModPath = path; + var modlps = new LpsDocument(File.ReadAllText(Path.Combine(path + @"\info.lps"))); + Name = modlps.FindLine("vupmod").Info; + Intro = modlps.FindLine("intro").Info; + GameVer = modlps.FindSub("gamever").InfoToInt; + Ver = modlps.FindSub("ver").InfoToInt; + Author = modlps.FindSub("author").Info.Split('[').First(); + if (modlps.FindLine("authorid") != null) + AuthorID = modlps.FindLine("authorid").InfoToInt64; + else + AuthorID = 0; + if (modlps.FindLine("itemid") != null) + ItemID = Convert.ToUInt64(modlps.FindLine("itemid").info); + else + ItemID = 0; + CacheDate = modlps.GetDateTime("cachedate", DateTime.MinValue); + var imagePath = Path.Combine(path, "icon.png"); + if (File.Exists(imagePath)) + { + try + { + Image = Utils.LoadImageToStream(imagePath); + } + catch { } + } + foreach (var dir in Directory.EnumerateDirectories(path)) + { + switch (dir.ToLower()) + { + case "pet": + //宠物模型 + Tags.Add("pet"); + break; + case "food": + Tags.Add("food"); + break; + case "image": + Tags.Add("image"); + break; + case "text": + Tags.Add("text"); + break; + case "lang": + Tags.Add("lang"); + break; + } + } + } +} diff --git a/VPet.Solution/Models/SettingEditor/CustomizedSettingModel.cs b/VPet.Solution/Models/SettingEditor/CustomizedSettingModel.cs new file mode 100644 index 0000000..3cdc518 --- /dev/null +++ b/VPet.Solution/Models/SettingEditor/CustomizedSettingModel.cs @@ -0,0 +1,55 @@ +using System.Collections.ObjectModel; + +namespace VPet.Solution.Models.SettingEditor; + +public class CustomizedSettingModel : ObservableClass +{ + public const string TargetName = "diy"; + + #region Links + private ObservableCollection _links = new(); + public ObservableCollection Links + { + get => _links; + set => SetProperty(ref _links, value); + } + #endregion +} + +public class LinkModel : ObservableClass +{ + #region Name + private string _name; + + /// + /// 名称 + /// + public string Name + { + get => _name; + set => SetProperty(ref _name, value); + } + #endregion + + + #region Link + private string _link; + + /// + /// 链接 + /// + public string Link + { + get => _link; + set => SetProperty(ref _link, value); + } + #endregion + + public LinkModel() { } + + public LinkModel(string name, string link) + { + Name = name; + Link = link; + } +} diff --git a/VPet.Solution/Models/SettingEditor/DiagnosticSettingModel.cs b/VPet.Solution/Models/SettingEditor/DiagnosticSettingModel.cs new file mode 100644 index 0000000..d9f9329 --- /dev/null +++ b/VPet.Solution/Models/SettingEditor/DiagnosticSettingModel.cs @@ -0,0 +1,68 @@ +using HKW.HKWUtils.Observable; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VPet_Simulator.Windows.Interface; + +namespace VPet.Solution.Models.SettingEditor; + +public class DiagnosticSettingModel : ObservableClass +{ + #region AutoCal + private bool _autoCal; + + /// + /// 自动修复超模 + /// + public bool AutoCal + { + get => _autoCal; + set => SetProperty(ref _autoCal, value); + } + #endregion + + #region Diagnosis + private bool _diagnosis; + + /// + /// 是否启用数据收集 + /// + [ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))] + public bool Diagnosis + { + get => _diagnosis; + set => SetProperty(ref _diagnosis, value); + } + #endregion + + #region DiagnosisInterval + private int _diagnosisInterval = 200; + + /// + /// 数据收集频率 + /// + [DefaultValue(200)] + [ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))] + public int DiagnosisInterval + { + get => _diagnosisInterval; + set => SetProperty(ref _diagnosisInterval, value); + } + public static ObservableCollection DiagnosisIntervals { get; } = + new() { 200, 500, 1000, 2000, 5000, 10000, 20000 }; + #endregion + + public void GetAutoCalFromSetting(Setting setting) + { + AutoCal = setting["gameconfig"].GetBool("noAutoCal") is false; + } + + public void SetAutoCalToSetting(Setting setting) + { + setting["gameconfig"].SetBool("noAutoCal", AutoCal is false); + } +} diff --git a/VPet.Solution/Models/SettingEditor/ModSettingModel.cs b/VPet.Solution/Models/SettingEditor/ModSettingModel.cs new file mode 100644 index 0000000..6e3c122 --- /dev/null +++ b/VPet.Solution/Models/SettingEditor/ModSettingModel.cs @@ -0,0 +1,287 @@ +using HKW.HKWUtils.Observable; +using LinePutScript; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using VPet_Simulator.Windows.Interface; + +namespace VPet.Solution.Models.SettingEditor; + +public class ModSettingModel : ObservableClass +{ + public const string ModLineName = "onmod"; + public const string PassModLineName = "passmod"; + public const string MsgModLineName = "msgmod"; + public static string ModDirectory = Path.Combine(Environment.CurrentDirectory, "mod"); + public static Dictionary LocalMods = Directory.Exists(ModDirectory) is false + ? new(StringComparer.OrdinalIgnoreCase) + : new( + Directory + .EnumerateDirectories(ModDirectory) + .Select(d => new ModLoader(d)) + .ToDictionary(m => m.Name, m => m), + StringComparer.OrdinalIgnoreCase + ); + #region Mods + private ObservableCollection _mods = new(); + public ObservableCollection Mods + { + get => _mods; + set => SetProperty(ref _mods, value); + } + + public ModSettingModel(Setting setting) + { + foreach (var item in setting[ModLineName]) + { + var modName = item.Name; + if (LocalMods.TryGetValue(modName, out var loader)) + { + var modModel = new ModModel(loader); + modModel.IsPass = setting[PassModLineName].Contains(modName); + modModel.IsMsg = setting[MsgModLineName].Contains(modModel.Name); + Mods.Add(modModel); + } + else + Mods.Add(new()); + } + } + + public void Close() + { + foreach (var modLoader in LocalMods) + { + modLoader.Value.Image.CloseStream(); + } + } + + public void Save(Setting setting) + { + setting.Remove(ModLineName); + setting.Remove(PassModLineName); + setting.Remove(MsgModLineName); + if (Mods.Any() is false) + return; + foreach (var mod in Mods) + { + setting[ModLineName].Add(new Sub(mod.Name.ToLower())); + setting[MsgModLineName].Add(new Sub(mod.Name, "True")); + if (mod.IsPass) + setting[PassModLineName].Add(new Sub(mod.Name.ToLower())); + } + } + #endregion +} + +public class ModModel : ObservableClass +{ + #region Name + private string _name; + + /// + /// 名称 + /// + [ReflectionProperty(nameof(ModLoader.Name))] + public string Name + { + get => _name; + set => SetProperty(ref _name, value); + } + #endregion + + #region Description + private string _description; + + /// + /// 描述 + /// + [ReflectionProperty(nameof(ModLoader.Intro))] + public string Description + { + get => _description; + set => SetProperty(ref _description, value); + } + #endregion + + #region Author + private string _author; + + /// + /// 作者 + /// + [ReflectionProperty(nameof(ModLoader.Author))] + public string Author + { + get => _author; + set => SetProperty(ref _author, value); + } + #endregion + + #region ModVersion + private int _modVersion; + + /// + /// 模组版本 + /// + [ReflectionProperty(nameof(ModLoader.Ver))] + public int ModVersion + { + get => _modVersion; + set => SetProperty(ref _modVersion, value); + } + #endregion + + #region GameVersion + private int _gameVersion; + + /// + /// 游戏版本 + /// + [ReflectionProperty(nameof(ModLoader.GameVer))] + public int GameVersion + { + get => _gameVersion; + set => SetProperty(ref _gameVersion, value); + } + #endregion + + #region Tags + private HashSet _tags; + + /// + /// 功能 + /// + [ReflectionProperty(nameof(ModLoader.Tags))] + public HashSet Tags + { + get => _tags; + set => SetProperty(ref _tags, value); + } + #endregion + + #region Image + private BitmapImage _image; + + /// + /// 图像 + /// + [ReflectionProperty(nameof(ModLoader.Image))] + public BitmapImage Image + { + get => _image; + set => SetProperty(ref _image, value); + } + #endregion + + #region ItemId + private ulong _itemId; + + [ReflectionProperty(nameof(ModLoader.ItemID))] + public ulong ItemId + { + get => _itemId; + set => SetProperty(ref _itemId, value); + } + #endregion + + + #region ModPath + + private string _modPath; + + [ReflectionProperty(nameof(ModLoader.ModPath))] + public string ModPath + { + get => _modPath; + set => SetProperty(ref _modPath, value); + } + #endregion + + #region IsEnabled + private bool? _isEnabled = true; + + /// + /// 已启用 + /// + public bool? IsEnabled + { + get => _isEnabled; + set => SetProperty(ref _isEnabled, value); + } + #endregion + + #region IsPass + private bool _isPass; + + /// + /// 是通过检查的代码模组 + /// + public bool IsPass + { + get => _isPass; + set => SetProperty(ref _isPass, value); + } + #endregion + + #region IsMsg + private bool _isMsg; + + /// + /// 是含有代码的模组 + /// + public bool IsMsg + { + get => _isMsg; + set => SetProperty(ref _isMsg, value); + } + #endregion + + #region State + private string _state; + public string State + { + get => _state; + set => SetProperty(ref _state, value); + } + #endregion + + + public ModModel() + { + PropertyChanged += ModModel_PropertyChanged; + IsEnabled = null; + } + + private void ModModel_PropertyChanged( + object sender, + System.ComponentModel.PropertyChangedEventArgs e + ) + { + if (e.PropertyName == nameof(IsEnabled)) + { + RefreshState(); + } + } + + public ModModel(ModLoader loader) + { + PropertyChanged += ModModel_PropertyChanged; + ReflectionUtils.SetValue(loader, this); + RefreshState(); + } + + public void RefreshState() + { + if (IsEnabled is true) + State = "已启用"; + else if (IsEnabled is false) + State = "已关闭"; + else + State = "已损坏"; + } +} diff --git a/VPet.Solution/Models/SettingEditor/SettingModel.cs b/VPet.Solution/Models/SettingEditor/SettingModel.cs index fc0c552..a3be916 100644 --- a/VPet.Solution/Models/SettingEditor/SettingModel.cs +++ b/VPet.Solution/Models/SettingEditor/SettingModel.cs @@ -50,12 +50,37 @@ public class SettingModel : ObservableClass } #endregion - private static HashSet _settingProperties = - new(typeof(Setting).GetProperties().Select(p => p.Name)); + #region CustomizedSetting + private CustomizedSettingModel _CustomizedSetting; + public CustomizedSettingModel CustomizedSetting + { + get => _CustomizedSetting; + set => SetProperty(ref _CustomizedSetting, value); + } + #endregion - private Setting _setting; + #region DiagnosticSetting + private DiagnosticSettingModel _diagnosticSetting; + public DiagnosticSettingModel DiagnosticSetting + { + get => _diagnosticSetting; + set => SetProperty(ref _diagnosticSetting, value); + } + #endregion - private ReflectionOptions _saveReflectionOptions = new() { CheckValueEquals = true }; + #region ModSetting + private ModSettingModel _modSetting; + public ModSettingModel ModSetting + { + get => _modSetting; + set => SetProperty(ref _modSetting, value); + } + #endregion + + + private readonly Setting _setting; + + private readonly ReflectionOptions _saveReflectionOptions = new() { CheckValueEquals = true }; public SettingModel() : this(new("")) { } @@ -66,14 +91,39 @@ public class SettingModel : ObservableClass GraphicsSetting = LoadSetting(); InteractiveSetting = LoadSetting(); SystemSetting = LoadSetting(); + CustomizedSetting = LoadCustomizedSetting(setting); + DiagnosticSetting = LoadSetting(); + DiagnosticSetting.SetAutoCalToSetting(setting); + ModSetting = LoadModSetting(setting); + } + + private ModSettingModel LoadModSetting(Setting setting) + { + var settingModel = new ModSettingModel(setting); + return settingModel; + } + + private CustomizedSettingModel LoadCustomizedSetting(Setting setting) + { + var model = new CustomizedSettingModel(); + if (setting[CustomizedSettingModel.TargetName] is ILine line && line.Count > 0) + { + foreach (var sub in line) + model.Links.Add(new(sub.Name, sub.Info)); + } + else + { + setting.Remove(CustomizedSettingModel.TargetName); + } + return model; } private T LoadSetting() where T : new() { - var setting = new T(); - ReflectionUtils.SetValue(_setting, setting); - return setting; + var settingModel = new T(); + ReflectionUtils.SetValue(_setting, settingModel); + return settingModel; } public void Save() @@ -81,11 +131,16 @@ public class SettingModel : ObservableClass SaveSetting(GraphicsSetting); SaveSetting(InteractiveSetting); SaveSetting(SystemSetting); + SaveSetting(DiagnosticSetting); + DiagnosticSetting.SetAutoCalToSetting(_setting); + foreach (var link in CustomizedSetting.Links) + _setting[CustomizedSettingModel.TargetName].Add(new Sub(link.Name, link.Link)); + ModSetting.Save(_setting); File.WriteAllText(FilePath, _setting.ToString()); } - private void SaveSetting(object setting) + private void SaveSetting(object settingModel) { - ReflectionUtils.SetValue(setting, _setting, _saveReflectionOptions); + ReflectionUtils.SetValue(settingModel, _setting, _saveReflectionOptions); } } diff --git a/VPet.Solution/Models/SettingEditor/SystemSettingModel.cs b/VPet.Solution/Models/SettingEditor/SystemSettingModel.cs index e5c5394..87b974a 100644 --- a/VPet.Solution/Models/SettingEditor/SystemSettingModel.cs +++ b/VPet.Solution/Models/SettingEditor/SystemSettingModel.cs @@ -9,34 +9,6 @@ public class SystemSettingModel : ObservableClass /// public bool DiagnosisDayEnable { get; } = true; - #region Diagnosis - private bool _diagnosis; - - /// - /// 是否启用数据收集 - /// - [ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))] - public bool Diagnosis - { - get => _diagnosis; - set => SetProperty(ref _diagnosis, value); - } - #endregion - - #region DiagnosisInterval - private int _diagnosisInterval; - - /// - /// 数据收集频率 - /// - [ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))] - public int DiagnosisInterval - { - get => _diagnosisInterval; - set => SetProperty(ref _diagnosisInterval, value); - } - #endregion - #region AutoSaveInterval private int _autoSaveInterval; diff --git a/VPet.Solution/SimpleObservable/ObservableCommand/ExecuteAsyncEventHandler.cs b/VPet.Solution/SimpleObservable/ObservableCommand/ExecuteAsyncEventHandler.cs index 07004c4..6cb2552 100644 --- a/VPet.Solution/SimpleObservable/ObservableCommand/ExecuteAsyncEventHandler.cs +++ b/VPet.Solution/SimpleObservable/ObservableCommand/ExecuteAsyncEventHandler.cs @@ -8,5 +8,5 @@ public delegate Task ExecuteAsyncEventHandler(); /// /// 异步执行命令事件 /// -/// 值 +/// 参数 public delegate Task ExecuteAsyncEventHandler(T parameter); diff --git a/VPet.Solution/Utils/Utils.cs b/VPet.Solution/Utils/Utils.cs index 0e4e157..7b1aec3 100644 --- a/VPet.Solution/Utils/Utils.cs +++ b/VPet.Solution/Utils/Utils.cs @@ -18,21 +18,27 @@ public static class Utils public const int DecodePixelHeight = 250; public static char[] Separator { get; } = new char[] { '_' }; - //public static BitmapImage LoadImageToStream(string imagePath) - //{ - // BitmapImage bitmapImage = new(); - // bitmapImage.BeginInit(); - // bitmapImage.DecodePixelWidth = DecodePixelWidth; - // try - // { - // bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream; - // } - // finally - // { - // bitmapImage.EndInit(); - // } - // return bitmapImage; - //} + /// + /// 载入图片到流 + /// + /// 图片路径 + /// 图片 + public static BitmapImage LoadImageToStream(string imagePath) + { + if (string.IsNullOrWhiteSpace(imagePath) || File.Exists(imagePath) is false) + return null; + BitmapImage bitmapImage = new(); + bitmapImage.BeginInit(); + try + { + bitmapImage.StreamSource = new StreamReader(imagePath).BaseStream; + } + finally + { + bitmapImage.EndInit(); + } + return bitmapImage; + } /// /// 载入图片至内存流 @@ -100,7 +106,7 @@ public static class Utils /// 打开文件 /// /// 文件路径 - public static void OpenFile(string filePath) + public static void OpenLink(string filePath) { System.Diagnostics.Process .Start(new System.Diagnostics.ProcessStartInfo(filePath) { UseShellExecute = true }) diff --git a/VPet.Solution/VPet.Solution.csproj b/VPet.Solution/VPet.Solution.csproj index 1087f57..dfd2f13 100644 --- a/VPet.Solution/VPet.Solution.csproj +++ b/VPet.Solution/VPet.Solution.csproj @@ -90,15 +90,20 @@ + + + + + @@ -110,6 +115,7 @@ + diff --git a/VPet.Solution/ViewModels/SaveViewer/SaveWindowVM.cs b/VPet.Solution/ViewModels/SaveViewer/SaveWindowVM.cs index a12d9c2..f3a04ea 100644 --- a/VPet.Solution/ViewModels/SaveViewer/SaveWindowVM.cs +++ b/VPet.Solution/ViewModels/SaveViewer/SaveWindowVM.cs @@ -77,7 +77,7 @@ public class SaveWindowVM : ObservableClass private void OpenFileCommand_ExecuteCommand(SaveModel parameter) { - Utils.OpenFile(parameter.FilePath); + Utils.OpenLink(parameter.FilePath); } public void RefreshShowSaves(string name) diff --git a/VPet.Solution/ViewModels/SettingEditor/CustomizedSettingPageVM.cs b/VPet.Solution/ViewModels/SettingEditor/CustomizedSettingPageVM.cs index 7f38a71..7ba1b9f 100644 --- a/VPet.Solution/ViewModels/SettingEditor/CustomizedSettingPageVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/CustomizedSettingPageVM.cs @@ -1,9 +1,112 @@ -using System; +using HKW.HKWUtils.Observable; +using LinePutScript.Localization.WPF; +using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; +using VPet.Solution.Models.SettingEditor; namespace VPet.Solution.ViewModels.SettingEditor; -public class CustomizedSettingPageVM { } +public class CustomizedSettingPageVM : ObservableClass +{ + #region ObservableProperty + #region CustomizedSetting + + private CustomizedSettingModel _customizedSetting; + public CustomizedSettingModel CustomizedSetting + { + get => _customizedSetting; + set => SetProperty(ref _customizedSetting, value); + } + #endregion + + #region SearchSetting + private string _searchSetting; + public string SearchLink + { + get => _searchSetting; + set + { + SetProperty(ref _searchSetting, value); + RefreshShowLinks(value); + } + } + #endregion + + #region ShowLinks + private IEnumerable _showLinks; + public IEnumerable ShowLinks + { + get => _showLinks; + set => SetProperty(ref _showLinks, value); + } + #endregion + #endregion + + #region Command + public ObservableCommand AddLinkCommand { get; } = new(); + public ObservableCommand RemoveLinkCommand { get; } = new(); + public ObservableCommand ClearLinksCommand { get; } = new(); + #endregion + public CustomizedSettingPageVM() + { + SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX; + AddLinkCommand.ExecuteCommand += AddLinkCommand_ExecuteCommand; + RemoveLinkCommand.ExecuteCommand += RemoveLinkCommand_ExecuteCommand; + ClearLinksCommand.ExecuteCommand += ClearLinksCommand_ExecuteCommand; + } + + private void ClearLinksCommand_ExecuteCommand() + { + if ( + MessageBox.Show( + "确定清空吗".Translate(), + "", + MessageBoxButton.YesNo, + MessageBoxImage.Warning + ) + is not MessageBoxResult.Yes + ) + return; + SearchLink = string.Empty; + CustomizedSetting.Links.Clear(); + } + + private void AddLinkCommand_ExecuteCommand() + { + SearchLink = string.Empty; + CustomizedSetting.Links.Add(new()); + } + + private void RemoveLinkCommand_ExecuteCommand(LinkModel parameter) + { + CustomizedSetting.Links.Remove(parameter); + } + + private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e) + { + if ( + e.PropertyName == nameof(SettingWindowVM.CurrentSetting) + && sender.CurrentSetting is not null + ) + { + CustomizedSetting = sender.CurrentSetting.CustomizedSetting; + SearchLink = string.Empty; + } + } + + public void RefreshShowLinks(string name) + { + if (string.IsNullOrWhiteSpace(name)) + ShowLinks = CustomizedSetting.Links; + else + ShowLinks = CustomizedSetting.Links.Where( + s => s.Name.Contains(SearchLink, StringComparison.OrdinalIgnoreCase) + ); + } +} diff --git a/VPet.Solution/ViewModels/SettingEditor/DiagnosticSettingPageVM.cs b/VPet.Solution/ViewModels/SettingEditor/DiagnosticSettingPageVM.cs index 7d7b780..4e92bfa 100644 --- a/VPet.Solution/ViewModels/SettingEditor/DiagnosticSettingPageVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/DiagnosticSettingPageVM.cs @@ -3,7 +3,32 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using VPet.Solution.Models.SettingEditor; namespace VPet.Solution.ViewModels.SettingEditor; -public class DiagnosticSettingPageVM { } +public class DiagnosticSettingPageVM : ObservableClass +{ + private DiagnosticSettingModel _diagnosticSetting; + public DiagnosticSettingModel DiagnosticSetting + { + get => _diagnosticSetting; + set => SetProperty(ref _diagnosticSetting, value); + } + + public DiagnosticSettingPageVM() + { + SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX; + } + + private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e) + { + if ( + e.PropertyName == nameof(SettingWindowVM.CurrentSetting) + && sender.CurrentSetting is not null + ) + { + DiagnosticSetting = sender.CurrentSetting.DiagnosticSetting; + } + } +} diff --git a/VPet.Solution/ViewModels/SettingEditor/ModSettingModelModel.cs b/VPet.Solution/ViewModels/SettingEditor/ModSettingModelModel.cs new file mode 100644 index 0000000..709f687 --- /dev/null +++ b/VPet.Solution/ViewModels/SettingEditor/ModSettingModelModel.cs @@ -0,0 +1,5 @@ +namespace VPet.Solution.ViewModels.SettingEditor; + +internal class ModSettingModelModel +{ +} \ No newline at end of file diff --git a/VPet.Solution/ViewModels/SettingEditor/ModSettingPageVM.cs b/VPet.Solution/ViewModels/SettingEditor/ModSettingPageVM.cs index c5d63c4..cc277d2 100644 --- a/VPet.Solution/ViewModels/SettingEditor/ModSettingPageVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/ModSettingPageVM.cs @@ -1,9 +1,164 @@ -using System; +using HKW.HKWUtils.Observable; +using LinePutScript.Localization.WPF; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows; +using VPet.Solution.Models.SettingEditor; namespace VPet.Solution.ViewModels.SettingEditor; -public class ModSettingPageVM { } +public class ModSettingPageVM : ObservableClass +{ + #region ObservableProperty + private ModSettingModel _modSetting; + public ModSettingModel ModSetting + { + get => _modSetting; + set => SetProperty(ref _modSetting, value); + } + + #region ShowMods + private IEnumerable _showMods; + public IEnumerable ShowMods + { + get => _showMods; + set => SetProperty(ref _showMods, value); + } + #endregion + + #region SearchMod + private string _searchMod; + public string SearchMod + { + get => _searchMod; + set + { + SetProperty(ref _searchMod, value); + RefreshShowMods(value); + } + } + #endregion + + #region CurrentModMoel + private ModModel _currentModModel; + public ModModel CurrentModMoel + { + get => _currentModModel; + set + { + if (_currentModModel is not null) + _currentModModel.PropertyChangingX -= CurrentModModel_PropertyChangingX; + SetProperty(ref _currentModModel, value); + if (value is not null) + _currentModModel.PropertyChangingX += CurrentModModel_PropertyChangingX; + } + } + + private void CurrentModModel_PropertyChangingX(ModModel sender, PropertyChangingXEventArgs e) + { + if (e.PropertyName == nameof(ModModel.IsPass) && e.NewValue is true) + { + if ( + MessageBox.Show( + "是否启用 {0} 的代码插件?\n一经启用,该插件将会允许访问该系统(包括外部系统)的所有数据\n如果您不确定,请先使用杀毒软件查杀检查".Translate( + sender.Name + ), + "启用 {0} 的代码插件?".Translate(sender.Name), + MessageBoxButton.YesNo, + MessageBoxImage.Warning + ) is MessageBoxResult.Yes + ) + { + sender.IsEnabled = true; + } + else + e.Cancel = true; + } + } + #endregion + + + #endregion + + #region Command + //public ObservableCommand AddModCommand { get; } = new(); + //public ObservableCommand RemoveModCommand { get; } = new(); + public ObservableCommand ClearFailModsCommand { get; } = new(); + public ObservableCommand ClearModsCommand { get; } = new(); + public ObservableCommand OpenModPathCommand { get; } = new(); + public ObservableCommand OpenSteamCommunityCommand { get; } = new(); + #endregion + + + public ModSettingPageVM() + { + SettingWindowVM.Current.PropertyChangedX += Current_PropertyChangedX; + ClearFailModsCommand.ExecuteCommand += ClearFailModsCommand_ExecuteCommand; + ClearModsCommand.ExecuteCommand += ClearModsCommand_ExecuteCommand; + OpenModPathCommand.ExecuteCommand += OpenModPathCommand_ExecuteCommand; + OpenSteamCommunityCommand.ExecuteCommand += OpenSteamCommunityCommand_ExecuteCommand; + } + + private void ClearModsCommand_ExecuteCommand() + { + if ( + MessageBox.Show("确定清除全部模组吗", "", MessageBoxButton.YesNo, MessageBoxImage.Warning) + is not MessageBoxResult.Yes + ) + return; + ModSetting.Mods.Clear(); + SearchMod = string.Empty; + } + + private void ClearFailModsCommand_ExecuteCommand() + { + if ( + MessageBox.Show("确定清除全部失效模组吗", "", MessageBoxButton.YesNo, MessageBoxImage.Warning) + is not MessageBoxResult.Yes + ) + return; + foreach (var mod in ModSetting.Mods.AsEnumerable()) + { + if (mod.IsEnabled is null) + ModSetting.Mods.Remove(mod); + } + SearchMod = string.Empty; + } + + private void OpenSteamCommunityCommand_ExecuteCommand(ModModel parameter) + { + Utils.OpenLink( + "https://steamcommunity.com/sharedfiles/filedetails/?id=" + parameter.ItemId + ); + } + + private void OpenModPathCommand_ExecuteCommand(ModModel parameter) + { + Utils.OpenLink(parameter.ModPath); + } + + private void Current_PropertyChangedX(SettingWindowVM sender, PropertyChangedXEventArgs e) + { + if ( + e.PropertyName == nameof(SettingWindowVM.CurrentSetting) + && sender.CurrentSetting is not null + ) + { + ModSetting = sender.CurrentSetting.ModSetting; + SearchMod = string.Empty; + } + } + + public void RefreshShowMods(string name) + { + if (string.IsNullOrWhiteSpace(name)) + ShowMods = ModSetting.Mods; + else + ShowMods = ModSetting.Mods.Where( + s => s.Name.Contains(SearchMod, StringComparison.OrdinalIgnoreCase) + ); + } +} diff --git a/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs b/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs index e86fcc6..f9ef59a 100644 --- a/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs +++ b/VPet.Solution/ViewModels/SettingEditor/SettingWindowVM.cs @@ -94,7 +94,7 @@ public class SettingWindowVM : ObservableClass private void OpenFileCommand_ExecuteCommand(SettingModel parameter) { - Utils.OpenFile(parameter.FilePath); + Utils.OpenLink(parameter.FilePath); } private void SaveAllSettingCommand_ExecuteCommand() diff --git a/VPet.Solution/Views/SettingEditor/CustomizedSettingPage.xaml b/VPet.Solution/Views/SettingEditor/CustomizedSettingPage.xaml index 13ea90c..23c9235 100644 --- a/VPet.Solution/Views/SettingEditor/CustomizedSettingPage.xaml +++ b/VPet.Solution/Views/SettingEditor/CustomizedSettingPage.xaml @@ -3,6 +3,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:h="clr-namespace:HKW.WPF.Helpers" xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF" xmlns:local="clr-namespace:VPet.Solution.Views.SettingEditor" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" @@ -15,43 +16,80 @@ mc:Ignorable="d"> - - - - - - - - - - - - - - -