Merge branch 'LorisYounger:main' into main

This commit is contained in:
Dragon Taki 2024-01-31 08:02:46 +08:00 committed by GitHub
commit daa58465a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 1798 additions and 509 deletions

View File

@ -8,6 +8,7 @@
<FileVersion>1.0.0.0</FileVersion>
<Product>VPet-Simulator.Tool</Product>
<Copyright>Copyright © 2022</Copyright>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">

View File

@ -7,6 +7,7 @@
<UseWPF>true</UseWPF>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@ -323,7 +323,11 @@ namespace VPet_Simulator.Windows
}
catch
{
Process.Start("explorer.exe", url);
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "explorer.exe";
startInfo.UseShellExecute = false;
startInfo.Arguments = url;
Process.Start(startInfo);
}
}

View File

@ -318,17 +318,37 @@ namespace VPet_Simulator.Windows
petHelper.Show();
}
public static void RunDIY(string content)
public void RunDIY(string content)
{
if (content.Contains("://") || content.Contains(@":\"))
if (content.Contains(@":\"))
{
try
{
Process.Start(content);
if (!Set["v"][(gbol)"rundiy"])
{
MessageBoxX.Show("由于操作系统的设计通过我们软件启动的程序可能会在任务管理器中归类为我们软件的子进程这可能导致CPU/内存占用显示较高".Translate(),
"关于CPU/内存占用显示较高的一次性提示".Translate());
Set["v"][(gbol)"rundiy"] = true;
}
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = content;
startInfo.UseShellExecute = false;
Process.Start(startInfo);
}
catch (Exception e)
{
MessageBox.Show("快捷键运行失败:无法运行指定内容".Translate() + '\n' + e.Message);
MessageBoxX.Show("快捷键运行失败:无法运行指定内容".Translate() + '\n' + e.Message);
}
}
else if (content.Contains("://"))
{
try
{
ExtensionSetting.StartURL(content);
}
catch (Exception e)
{
MessageBoxX.Show("快捷键运行失败:无法运行指定内容".Translate() + '\n' + e.Message);
}
}
else
@ -339,7 +359,7 @@ namespace VPet_Simulator.Windows
}
catch (Exception e)
{
MessageBox.Show("快捷键运行失败:无法运行指定内容".Translate() + '\n' + e.Message);
MessageBoxX.Show("快捷键运行失败:无法运行指定内容".Translate() + '\n' + e.Message);
}
}
}

View File

@ -20,6 +20,7 @@ using Line = LinePutScript.Line;
using static VPet_Simulator.Core.GraphInfo;
using System.Globalization;
using LinePutScript.Dictionary;
using Steamworks.Data;
namespace VPet_Simulator.Windows
{
@ -111,6 +112,8 @@ namespace VPet_Simulator.Windows
{
if (IsSteamUser)//如果是steam用户,尝试加载workshop
{
//Leaderboard? leaderboard = await SteamUserStats.FindLeaderboardAsync("chatgpt_auth");
//leaderboard?.ReplaceScore(Function.Rnd.Next());
var workshop = new Line_D("workshop");
await Dispatcher.InvokeAsync(new Action(() =>
{
@ -126,7 +129,7 @@ namespace VPet_Simulator.Windows
int i = 1;
while (true)
{
var page = await Steamworks.Ugc.Query.ItemsReadyToUse.GetPageAsync(i++);
var page = await Steamworks.Ugc.Query.ItemsReadyToUse.GetPageAsync(i++);
if (page.HasValue && page.Value.ResultCount != 0)
{
foreach (Steamworks.Ugc.Item entry in page.Value.Entries)
@ -260,7 +263,7 @@ namespace VPet_Simulator.Windows
if (App.MainWindows.Count <= 1)
{
try
{
{
if (Core != null && Core.Graph != null)
{
foreach (var igs in Core.Graph.GraphsList.Values)

View File

@ -6,6 +6,7 @@ mklink /d "%~dp0\bin\x64\Debug\net462\mod" "%~dp0\mod"
echo The following is the automatic link generation for other related MODs. If an error is prompted, it is a normal phenomenon and can be ignored
mklink /d "%~dp0\bin\x64\Release\net462\mod" "%~dp0\mod"
mklink /d "%~dp0\..\VPet.Solution\bin\Debug\mod" "%~dp0\mod"
mklink /d "%~dp0\mod\0001_ModMaker" "%~dp0\..\..\VPet.ModMaker\0001_ModMaker"
mklink /d "%~dp0\mod\1100_DemoClock" "%~dp0\..\..\VPet.Plugin.Demo\VPet.Plugin.DemoClock\1100_DemoClock"

View File

@ -0,0 +1,2 @@
由于操作系统的设计通过我们软件启动的程序可能会在任务管理器中归类为我们软件的子进程这可能导致CPU/内存占用显示较高#Due to the design of the operating system, programs launched by our software may be categorized as sub-processes of our software in the task manager, which may result in higher displayed CPU/memory usage.:|
关于CPU/内存占用显示较高的一次性提示#One-time Notice Regarding Higher Displayed CPU/Memory Usage:|

View File

@ -0,0 +1,48 @@
VPET 设置编辑器#VPET Setup Editor:|
打开文件#Opening Files:|
从资源管理器打开文件#Opening a file from Explorer:|
重置#Reset:|
全部保存#Save All:|
Mod管理#Mod Management:|
保存为退出位置#Save as Exit Location:|
设为当前位置#Set as current position:|
设为当前窗口左上角顶点坐标的位置#Set to the current position of the top-left corner of the window in vertex coordinates.:|
每次间隔#Interval:|
备份设置#Backup Settings:|
桌宠设置#VPet Settings:|
桌宠状态#VPet Status:|
启用桌宠状态#Enable VPet status:|
分钟左右主动进行一次互动 (走路发呆爬墙等) #Interact actively once every minute or so (walk, dawdle, climb walls, etc.) :|
清空全部#Clear all:|
搜索名称#Search Name:|
链接#Link:|
每周期一次#Once per cycle:|
搜索模组#Search Module:|
清除失效模组#Clear invalid modules:|
清除全部模组#Clear all modules:|
模组名称:#Module Name.:|
作者:#Author.:|
模组版本:#Module Version.:|
游戏版本:#Game Version.:|
模组路径:#Path to Module.:|
启用模组#Enable Module:|
启用模组代码#Enable Module Code:|
打开所在文件夹#Open the folder:|
打开创意工坊页面#Open Creative Workshop Page:|
VPET 存档查看器#VPET Archive Viewer:|
搜索存档#Search Archives:|
保存时间#Save Time:|
游玩时长#Play Duration:|
数据#Data:|
保存日期#Save Dates:|
模式#Mode:|
等级#Grade:|
哈希检查#Hash Check:|
值#Value:|
VPET 问题解决工具#VPET Problem Solving Tool:|
打开设置编辑器#Open Settings Editor:|
打开存档查看器#Open Archive Viewer:|
打开翻译文本#Open Translated Text:|
全部重置#Reset All:|
哈希#Hash:|
第一次启动桌宠打不开?#Can't open the first time you start the desktop pet?:|

View File

@ -0,0 +1,2 @@
由于操作系统的设计通过我们软件启动的程序可能会在任务管理器中归类为我们软件的子进程这可能导致CPU/内存占用显示较高#由于操作系统的设计通过我们软件启动的程序可能会在任务管理器中归类为我们软件的子进程这可能导致CPU/内存占用显示较高:|
关于CPU/内存占用显示较高的一次性提示#关于CPU/内存占用显示较高的一次性提示:|

View File

@ -0,0 +1,48 @@
VPET 设置编辑器#VPET 设置编辑器:|
打开文件#打开文件:|
从资源管理器打开文件#从资源管理器打开文件:|
重置#重置:|
全部保存#全部保存:|
Mod管理#Mod管理:|
保存为退出位置#保存为退出位置:|
设为当前位置#设为当前位置:|
设为当前窗口左上角顶点坐标的位置#设为当前窗口左上角顶点坐标的位置:|
每次间隔#每次间隔:|
备份设置#备份设置:|
桌宠设置#桌宠设置:|
桌宠状态#桌宠状态:|
启用桌宠状态#启用桌宠状态:|
分钟左右主动进行一次互动 (走路发呆爬墙等) #分钟左右主动进行一次互动 (走路发呆爬墙等) :|
清空全部#清空全部:|
搜索名称#搜索名称:|
链接#链接:|
每周期一次#每周期一次:|
搜索模组#搜索模组:|
清除失效模组#清除失效模组:|
清除全部模组#清除全部模组:|
模组名称:#模组名称::|
作者:#作者::|
模组版本:#模组版本::|
游戏版本:#游戏版本::|
模组路径:#模组路径::|
启用模组#启用模组:|
启用模组代码#启用模组代码:|
打开所在文件夹#打开所在文件夹:|
打开创意工坊页面#打开创意工坊页面:|
VPET 存档查看器#VPET 存档查看器:|
搜索存档#搜索存档:|
保存时间#保存时间:|
游玩时长#游玩时长:|
数据#数据:|
保存日期#保存日期:|
模式#模式:|
等级#等级:|
哈希检查#哈希检查:|
值#值:|
VPET 问题解决工具#VPET 问题解决工具:|
打开设置编辑器#打开设置编辑器:|
打开存档查看器#打开存档查看器:|
打开翻译文本#打开翻译文本:|
全部重置#全部重置:|
哈希#哈希:|
第一次启动桌宠打不开?#第一次启动桌宠打不开?:|

View File

@ -0,0 +1,2 @@
由于操作系统的设计通过我们软件启动的程序可能会在任务管理器中归类为我们软件的子进程这可能导致CPU/内存占用显示较高#由於操作系統的設計透過我們軟體啟動的程序可能會在任務管理器中歸類為我們軟體的子進程這可能導致CPU/內存占用顯示較高:|
关于CPU/内存占用显示较高的一次性提示#關於CPU/內存占用顯示較高的一次性提示:|

View File

@ -0,0 +1,48 @@
VPET 设置编辑器#VPET設定編輯器:|
打开文件#打開文件:|
从资源管理器打开文件#從資料總管打開文件:|
重置#重置:|
全部保存#全部保存:|
Mod管理#Mod管理:|
保存为退出位置#保存為退出位置:|
设为当前位置#設為當前位置:|
设为当前窗口左上角顶点坐标的位置#設為當前視窗左上角頂點座標的位置:|
每次间隔#每次間隔:|
备份设置#備份設定:|
桌宠设置#桌寵設定:|
桌宠状态#桌寵狀態:|
启用桌宠状态#啟用桌寵狀態:|
分钟左右主动进行一次互动 (走路发呆爬墙等) #分鐘左右主動進行一次互動(走路發呆爬牆等):|
清空全部#清空全部:|
搜索名称#蒐索名稱:|
链接#鏈接:|
每周期一次#每週期一次:|
搜索模组#蒐索模組:|
清除失效模组#清除失效模組:|
清除全部模组#清除全部模組:|
模组名称:#模組名稱::|
作者:#作者::|
模组版本:#模組版本::|
游戏版本:#遊戲版本::|
模组路径:#模組路徑::|
启用模组#啟用模組:|
启用模组代码#啟用模組程式碼:|
打开所在文件夹#打開所在資料夾:|
打开创意工坊页面#打開創意工坊頁面:|
VPET 存档查看器#VPET存檔檢視器:|
搜索存档#蒐索存檔:|
保存时间#保存時間:|
游玩时长#遊玩時長:|
数据#數據:|
保存日期#保存日期:|
模式#模式:|
等级#等級:|
哈希检查#雜湊檢查:|
值#值:|
VPET 问题解决工具#VPET問題解决工具:|
打开设置编辑器#打開設定編輯器:|
打开存档查看器#打開存檔檢視器:|
打开翻译文本#打開翻譯文字:|
全部重置#全部重置:|
哈希#雜湊:|
第一次启动桌宠打不开?#第一次啟動桌寵打不開?:|

View File

@ -8,6 +8,16 @@
<c:StringFormatConverter x:Key="StringFormatConverter" />
<c:BrushToMediaColorConverter x:Key="BrushToMediaColorConverter" />
<c:BoolToVisibilityConverter x:Key="FalseToHiddenConverter" />
<c:BoolToVisibilityConverter
x:Key="FalseToVisibleConverter"
FalseVisibilityValue="Visible"
NullValue="True"
TrueVisibilityValue="Hidden" />
<c:NullToVisibilityConverter x:Key="NotNullToVisibleConverter" />
<c:NullToVisibilityConverter
x:Key="NullToVisibleConverter"
NotNullVisibilityValue="Hidden"
NullVisibilityValue="Visible" />
<c:EqualsConverter x:Key="EqualsConverter" />
<c:EqualsConverter x:Key="NotEqualsConverter" Inverter="True" />
<c:ValueToBoolConverter x:Key="NullToFalse" Invert="True" />

View File

@ -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)
);

View File

@ -0,0 +1,60 @@
using System.ComponentModel;
using System.Globalization;
using System.Windows;
namespace HKW.WPF.Converters;
public class NullToVisibilityConverter : ValueConverterBase
{
/// <summary>
///
/// </summary>
public static readonly DependencyProperty NullVisibilityValueProperty =
DependencyProperty.Register(
nameof(NullVisibilityValue),
typeof(Visibility),
typeof(NullToVisibilityConverter),
new PropertyMetadata(Visibility.Hidden)
);
/// <summary>
/// NULL时的可见度
/// </summary>
[DefaultValue(Visibility.Hidden)]
public Visibility NullVisibilityValue
{
get => (Visibility)GetValue(NullVisibilityValueProperty);
set => SetValue(NullVisibilityValueProperty, value);
}
/// <summary>
///
/// </summary>
public static readonly DependencyProperty NotNullVisibilityValueProperty =
DependencyProperty.Register(
nameof(NotNullVisibilityValue),
typeof(Visibility),
typeof(NullToVisibilityConverter),
new PropertyMetadata(Visibility.Visible)
);
/// <summary>
/// 不为NULL时的可见度
/// </summary>
[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;
}
}

View File

@ -0,0 +1,167 @@
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;
using LinePutScript.Localization.WPF;
namespace VPet.Solution.Models;
/// <summary>
/// 模组加载器
/// </summary>
public class ModLoader
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; }
/// <summary>
/// 如果是上传至Steam,则为SteamUserID
/// </summary>
public long AuthorID { get; }
/// <summary>
/// 上传至Steam的ItemID
/// </summary>
public ulong ItemID { get; }
/// <summary>
/// 简介
/// </summary>
public string Intro { get; }
/// <summary>
/// 模组路径
/// </summary>
public string ModPath { get; }
/// <summary>
/// 支持的游戏版本
/// </summary>
public int GameVer { get; }
/// <summary>
/// 版本
/// </summary>
public int Ver { get; }
/// <summary>
/// 标签
/// </summary>
public HashSet<string> Tags { get; } = new();
/// <summary>
/// 缓存数据
/// </summary>
public DateTime CacheDate { get; } = DateTime.MinValue;
public BitmapImage? Image { get; } = null;
/// <summary>
/// 读取成功
/// </summary>
public bool IsSuccesses { get; } = true;
public ModLoader(string path)
{
ModPath = path;
var infoFile = Path.Combine(path, "info.lps");
if (File.Exists(infoFile) is false)
{
Name = Path.GetFileName(path);
IsSuccesses = false;
return;
}
var modlps = new LpsDocument(File.ReadAllText(infoFile));
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");
//加载翻译
foreach (var line in modlps.FindAllLine("lang"))
{
var lps = new LPS();
foreach (var sub in line)
lps.Add(new Line(sub.Name, sub.Info));
LocalizeCore.AddCulture(line.Info, lps);
}
if (File.Exists(imagePath))
{
try
{
Image = Utils.LoadImageToStream(imagePath);
}
catch { }
}
foreach (var dir in Directory.EnumerateDirectories(path))
{
var dirName = Path.GetFileName(dir);
switch (dirName.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");
foreach (var langFile in Directory.EnumerateFiles(dir, "*.lps"))
{
LocalizeCore.AddCulture(
Path.GetFileNameWithoutExtension(dir),
new LPS_D(File.ReadAllText(langFile))
);
}
foreach (var langDir in Directory.EnumerateDirectories(dir))
{
foreach (var langFile in Directory.EnumerateFiles(langDir, "*.lps"))
{
LocalizeCore.AddCulture(
Path.GetFileNameWithoutExtension(langDir),
new LPS_D(File.ReadAllText(langFile))
);
}
}
break;
}
}
}
}

View File

@ -0,0 +1,55 @@
using System.Collections.ObjectModel;
namespace VPet.Solution.Models.SettingEditor;
public class CustomizedSettingModel : ObservableClass<CustomizedSettingModel>
{
public const string TargetName = "diy";
#region Links
private ObservableCollection<LinkModel> _links = new();
public ObservableCollection<LinkModel> Links
{
get => _links;
set => SetProperty(ref _links, value);
}
#endregion
}
public class LinkModel : ObservableClass<LinkModel>
{
#region Name
private string _name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
#endregion
#region Link
private string _link;
/// <summary>
/// 链接
/// </summary>
public string Link
{
get => _link;
set => SetProperty(ref _link, value);
}
#endregion
public LinkModel() { }
public LinkModel(string name, string link)
{
Name = name;
Link = link;
}
}

View File

@ -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<DiagnosticSettingModel>
{
#region AutoCal
private bool _autoCal;
/// <summary>
/// 自动修复超模
/// </summary>
public bool AutoCal
{
get => _autoCal;
set => SetProperty(ref _autoCal, value);
}
#endregion
#region Diagnosis
private bool _diagnosis;
/// <summary>
/// 是否启用数据收集
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))]
public bool Diagnosis
{
get => _diagnosis;
set => SetProperty(ref _diagnosis, value);
}
#endregion
#region DiagnosisInterval
private int _diagnosisInterval = 500;
/// <summary>
/// 数据收集频率
/// </summary>
[DefaultValue(500)]
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))]
public int DiagnosisInterval
{
get => _diagnosisInterval;
set => SetProperty(ref _diagnosisInterval, value);
}
public static ObservableCollection<int> 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);
}
}

View File

@ -0,0 +1,320 @@
using HKW.HKWUtils.Observable;
using LinePutScript;
using LinePutScript.Localization.WPF;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
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<ModSettingModel>
{
public const string ModLineName = "onmod";
public const string PassModLineName = "passmod";
public const string MsgModLineName = "msgmod";
public const string WorkShopLineName = "workshop";
public static string ModDirectory = Path.Combine(Environment.CurrentDirectory, "mod");
public static Dictionary<string, ModLoader> 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<ModModel> _mods = new();
public ObservableCollection<ModModel> 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) && loader.IsSuccesses)
{
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()
{
Name = modName,
ModPath = "未知, 可能是{0}".Translate(Path.Combine(ModDirectory, modName))
}
);
}
}
foreach (var modPath in setting[WorkShopLineName])
{
var loader = new ModLoader(modPath.Name);
if (loader.IsSuccesses is false)
{
Mods.Add(new() { Name = loader.Name, ModPath = loader.ModPath });
return;
}
var modModel = new ModModel(loader);
modModel.IsPass = setting[PassModLineName].Contains(modModel.Name);
modModel.IsMsg = setting[MsgModLineName].Contains(modModel.Name);
Mods.Add(modModel);
}
}
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<ModModel>
{
#region Name
private string _name;
/// <summary>
/// 名称
/// </summary>
[ReflectionProperty(nameof(ModLoader.Name))]
public string Name
{
get => _name;
set => SetProperty(ref _name, value);
}
#endregion
#region Description
private string _description;
/// <summary>
/// 描述
/// </summary>
[ReflectionProperty(nameof(ModLoader.Intro))]
public string Description
{
get => _description;
set => SetProperty(ref _description, value);
}
#endregion
#region Author
private string _author;
/// <summary>
/// 作者
/// </summary>
[ReflectionProperty(nameof(ModLoader.Author))]
public string Author
{
get => _author;
set => SetProperty(ref _author, value);
}
#endregion
#region ModVersion
private int _modVersion;
/// <summary>
/// 模组版本
/// </summary>
[ReflectionProperty(nameof(ModLoader.Ver))]
public int ModVersion
{
get => _modVersion;
set => SetProperty(ref _modVersion, value);
}
#endregion
#region GameVersion
private int _gameVersion;
/// <summary>
/// 游戏版本
/// </summary>
[ReflectionProperty(nameof(ModLoader.GameVer))]
public int GameVersion
{
get => _gameVersion;
set => SetProperty(ref _gameVersion, value);
}
#endregion
#region Tags
private HashSet<string> _tags;
/// <summary>
/// 功能
/// </summary>
[ReflectionProperty(nameof(ModLoader.Tags))]
public HashSet<string> Tags
{
get => _tags;
set => SetProperty(ref _tags, value);
}
#endregion
#region Image
private BitmapImage _image;
/// <summary>
/// 图像
/// </summary>
[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;
/// <summary>
/// 已启用
/// </summary>
public bool? IsEnabled
{
get => _isEnabled;
set => SetProperty(ref _isEnabled, value);
}
#endregion
#region IsPass
private bool _isPass;
/// <summary>
/// 是通过检查的代码模组
/// </summary>
public bool IsPass
{
get => _isPass;
set => SetProperty(ref _isPass, value);
}
#endregion
#region IsMsg
private bool _isMsg;
/// <summary>
/// 是含有代码的模组
/// </summary>
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()
{
IsEnabled = null;
RefreshState();
}
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();
Name = Name.Translate();
Description = Description.Translate();
LocalizeCore.BindingNotify.PropertyChanged += BindingNotify_PropertyChanged;
}
private void BindingNotify_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Name = Name.Translate();
Description = Description.Translate();
}
public void RefreshState()
{
if (IsEnabled is true)
State = "已启用".Translate();
else if (IsEnabled is false)
State = "已关闭".Translate();
else
State = "已损坏".Translate();
}
}

View File

@ -50,12 +50,37 @@ public class SettingModel : ObservableClass<SettingModel>
}
#endregion
private static HashSet<string> _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<SettingModel>
GraphicsSetting = LoadSetting<GraphicsSettingModel>();
InteractiveSetting = LoadSetting<InteractiveSettingModel>();
SystemSetting = LoadSetting<SystemSettingModel>();
CustomizedSetting = LoadCustomizedSetting(setting);
DiagnosticSetting = LoadSetting<DiagnosticSettingModel>();
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<T>()
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<SettingModel>
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);
}
}

View File

@ -9,34 +9,6 @@ public class SystemSettingModel : ObservableClass<SystemSettingModel>
/// </summary>
public bool DiagnosisDayEnable { get; } = true;
#region Diagnosis
private bool _diagnosis;
/// <summary>
/// 是否启用数据收集
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.Diagnosis))]
public bool Diagnosis
{
get => _diagnosis;
set => SetProperty(ref _diagnosis, value);
}
#endregion
#region DiagnosisInterval
private int _diagnosisInterval;
/// <summary>
/// 数据收集频率
/// </summary>
[ReflectionProperty(nameof(VPet_Simulator.Windows.Interface.Setting.DiagnosisInterval))]
public int DiagnosisInterval
{
get => _diagnosisInterval;
set => SetProperty(ref _diagnosisInterval, value);
}
#endregion
#region AutoSaveInterval
private int _autoSaveInterval;

View File

@ -8,5 +8,5 @@ public delegate Task ExecuteAsyncEventHandler();
/// <summary>
/// 异步执行命令事件
/// </summary>
/// <param name="parameter"></param>
/// <param name="parameter">参数</param>
public delegate Task ExecuteAsyncEventHandler<T>(T parameter);

View File

@ -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;
//}
/// <summary>
/// 载入图片到流
/// </summary>
/// <param name="imagePath">图片路径</param>
/// <returns>图片</returns>
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;
}
/// <summary>
/// 载入图片至内存流
@ -100,7 +106,7 @@ public static class Utils
/// 打开文件
/// </summary>
/// <param name="filePath">文件路径</param>
public static void OpenFile(string filePath)
public static void OpenLink(string filePath)
{
System.Diagnostics.Process
.Start(new System.Diagnostics.ProcessStartInfo(filePath) { UseShellExecute = true })

View File

@ -14,7 +14,6 @@
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -47,11 +46,11 @@
<HintPath>
..\packages\LinePutScript.Localization.WPF.1.0.6\lib\net462\LinePutScript.Localization.WPF.dll</HintPath>
</Reference>
<Reference Include="Panuon.WPF, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Panuon.WPF.1.0.2\lib\net462\Panuon.WPF.dll</HintPath>
<Reference Include="Panuon.WPF, Version=1.0.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Panuon.WPF.1.0.3\lib\net462\Panuon.WPF.dll</HintPath>
</Reference>
<Reference Include="Panuon.WPF.UI, Version=1.1.15.8, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Panuon.WPF.UI.1.1.15.8\lib\net462\Panuon.WPF.UI.dll</HintPath>
<Reference Include="Panuon.WPF.UI, Version=1.1.16.5, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Panuon.WPF.UI.1.1.16.5\lib\net462\Panuon.WPF.UI.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
@ -90,15 +89,20 @@
<Compile Include="Converters\IsBoolConverter.cs" />
<Compile Include="Converters\MarginConverter.cs" />
<Compile Include="Converters\MediaColorToBrushConverter.cs" />
<Compile Include="Converters\NullToVisibilityConverter.cs" />
<Compile Include="Converters\StringFormatConverter.cs" />
<Compile Include="Converters\BoolToVisibilityConverter.cs" />
<Compile Include="Converters\MaxConverter.cs" />
<Compile Include="Converters\ValueToBoolConverter.cs" />
<Compile Include="Converters\BoolInverter.cs" />
<Compile Include="Models\ModLoader.cs" />
<Compile Include="Models\SaveViewer\SaveModel.cs" />
<Compile Include="Models\SaveViewer\StatisticDataModel.cs" />
<Compile Include="Models\SettingEditor\CustomizedSettingModel.cs" />
<Compile Include="Models\SettingEditor\DiagnosticSettingModel.cs" />
<Compile Include="Models\SettingEditor\GraphicsSettingModel.cs" />
<Compile Include="Models\SettingEditor\InteractiveSettingModel.cs" />
<Compile Include="Models\SettingEditor\ModSettingModel.cs" />
<Compile Include="Models\SettingEditor\SystemSettingModel.cs" />
<Compile Include="Utils\ClearFocus.cs" />
<Compile Include="Utils\ElementHelper.cs" />
@ -110,6 +114,7 @@
<Compile Include="ViewModels\SaveViewer\SaveWindowVM.cs" />
<Compile Include="ViewModels\SettingEditor\CustomizedSettingPageVM.cs" />
<Compile Include="ViewModels\SettingEditor\DiagnosticSettingPageVM.cs" />
<Compile Include="ViewModels\SettingEditor\ModSettingModelModel.cs" />
<Compile Include="ViewModels\SettingEditor\ModSettingPageVM.cs" />
<Compile Include="Models\SettingEditor\SettingModel.cs" />
<Compile Include="ViewModels\SettingEditor\SystemSettingPageVM.cs" />

View File

@ -1,4 +1,7 @@
using System;
using HKW.HKWUtils.Observable;
using LinePutScript.Localization.WPF;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -6,4 +9,51 @@ using System.Threading.Tasks;
namespace VPet.Solution.ViewModels;
public class MainWindowVM : ObservableClass<MainWindowVM> { }
public class MainWindowVM : ObservableClass<MainWindowVM>
{
public MainWindowVM()
{
LocalizeCore.StoreTranslation = true;
LocalizeCore.LoadDefaultCulture();
CurrentCulture = LocalizeCore.CurrentCulture;
FirstStartFailedCommand.ExecuteCommand += FirstStartFailedCommand_ExecuteCommand;
OpenLocalTextCommand.ExecuteCommand += OpenLocalTextCommand_ExecuteCommand;
}
private void OpenLocalTextCommand_ExecuteCommand()
{
var sb = new StringBuilder();
foreach (var a in LocalizeCore.StoreTranslationList)
sb.AppendLine(a.Replace("\r\n", "\\r\\n"));
MessageBoxX.Show(sb.ToString());
}
private void FirstStartFailedCommand_ExecuteCommand()
{
if (LocalizeCore.CurrentCulture == "zh-Hans")
Utils.OpenLink("https://www.bilibili.com/read/cv26510496/");
else
Utils.OpenLink("https://steamcommunity.com/games/1920960/announcements/detail/3681184905256253203");
}
#region Property
public IEnumerable<string> AvailableCultures => LocalizeCore.AvailableCultures;
#region CurrentCulture
private string _currentCulture = string.Empty;
public string CurrentCulture
{
get => _currentCulture;
set
{
SetProperty(ref _currentCulture, value);
LocalizeCore.LoadCulture(_currentCulture);
}
}
#endregion
#endregion
#region Command
public ObservableCommand FirstStartFailedCommand { get; } = new();
public ObservableCommand OpenLocalTextCommand { get; } = new();
#endregion
}

View File

@ -77,7 +77,7 @@ public class SaveWindowVM : ObservableClass<SaveWindowVM>
private void OpenFileCommand_ExecuteCommand(SaveModel parameter)
{
Utils.OpenFile(parameter.FilePath);
Utils.OpenLink(parameter.FilePath);
}
public void RefreshShowSaves(string name)

View File

@ -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<CustomizedSettingPageVM>
{
#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<LinkModel> _showLinks;
public IEnumerable<LinkModel> ShowLinks
{
get => _showLinks;
set => SetProperty(ref _showLinks, value);
}
#endregion
#endregion
#region Command
public ObservableCommand AddLinkCommand { get; } = new();
public ObservableCommand<LinkModel> 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)
);
}
}

View File

@ -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<DiagnosticSettingPageVM>
{
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;
}
}
}

View File

@ -0,0 +1,5 @@
namespace VPet.Solution.ViewModels.SettingEditor;
internal class ModSettingModelModel
{
}

View File

@ -1,9 +1,171 @@
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<ModSettingPageVM>
{
#region ObservableProperty
private ModSettingModel _modSetting;
public ModSettingModel ModSetting
{
get => _modSetting;
set => SetProperty(ref _modSetting, value);
}
#region ShowMods
private IEnumerable<ModModel> _showMods;
public IEnumerable<ModModel> 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<ModModel> RemoveModCommand { get; } = new();
public ObservableCommand ClearFailModsCommand { get; } = new();
public ObservableCommand ClearModsCommand { get; } = new();
public ObservableCommand<ModModel> OpenModPathCommand { get; } = new();
public ObservableCommand<ModModel> 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)
{
try
{
Utils.OpenLink(parameter.ModPath);
}
catch
{
MessageBox.Show("未在路径\n{0}\n中找到模组".Translate(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)
);
}
}

View File

@ -72,6 +72,11 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
/// 保存全部
/// </summary>
public ObservableCommand SaveAllSettingCommand { get; } = new();
/// <summary>
/// 重置全部
/// </summary>
public ObservableCommand ResetAllSettingCommand { get; } = new();
#endregion
public SettingWindowVM()
{
@ -85,6 +90,24 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
ResetSettingCommand.ExecuteCommand += ResetSettingCommand_ExecuteCommand;
SaveSettingCommand.ExecuteCommand += SaveSettingCommand_ExecuteCommand;
SaveAllSettingCommand.ExecuteCommand += SaveAllSettingCommand_ExecuteCommand;
ResetAllSettingCommand.ExecuteCommand += ResetAllSettingCommand_ExecuteCommand;
}
private void ResetAllSettingCommand_ExecuteCommand()
{
if (
MessageBox.Show(
SettingWindow.Instance,
"确定全部重置吗".Translate(),
"",
MessageBoxButton.YesNo,
MessageBoxImage.Warning
)
is not MessageBoxResult.Yes
)
return;
for (var i = 0; i < _settings.Count; i++)
_settings[i] = new SettingModel();
}
private void OpenFileInExplorerCommand_ExecuteCommand(SettingModel parameter)
@ -94,7 +117,7 @@ public class SettingWindowVM : ObservableClass<SettingWindowVM>
private void OpenFileCommand_ExecuteCommand(SettingModel parameter)
{
Utils.OpenFile(parameter.FilePath);
Utils.OpenLink(parameter.FilePath);
}
private void SaveAllSettingCommand_ExecuteCommand()

View File

@ -1,39 +1,40 @@
<pu:WindowX
x:Class="VPet.Solution.Views.MainWindow"
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:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
xmlns:local="clr-namespace:VPet.Solution"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:vm="clr-namespace:VPet.Solution.ViewModels"
Title="{ll:Str 'VPET 问题解决工具'}"
Width="800"
Height="450"
MinWidth="400"
MinHeight="200"
d:DataContext="{d:DesignInstance Type=vm:MainWindowVM}"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="Button_OpenSettingEditor"
Click="Button_OpenSettingEditor_Click"
Content="{ll:Str 打开设置编辑器}"
FontSize="16"
Style="{DynamicResource Button_BaseStyle}" />
<Button
x:Name="Button_OpenSaveEditor"
Grid.Column="1"
Click="Button_OpenSaveEditor_Click"
Content="{ll:Str 打开存档查看器}"
FontSize="16"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<pu:WindowX x:Class="VPet.Solution.Views.MainWindow" 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:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF"
xmlns:local="clr-namespace:VPet.Solution" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pu="https://opensource.panuon.com/wpf-ui" xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:vm="clr-namespace:VPet.Solution.ViewModels" Title="{ll:Str 'VPET 问题解决工具'}" Width="400" Height="450"
MinWidth="400" MinHeight="200" d:DataContext="{d:DesignInstance Type=vm:MainWindowVM}"
WindowStartupLocation="CenterScreen" mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="200" />
<RowDefinition />
</Grid.RowDefinitions>
<Label Height="Auto" Content="{ll:Str 'VPET 问题解决工具'}" FontSize="32" Style="{DynamicResource Label_BaseStyle}" />
<ComboBox MinWidth="150" x:Name="ComboBox_Langs" Grid.Column="1" HorizontalAlignment="Right"
VerticalAlignment="Top" ItemsSource="{Binding AvailableCultures}"
SelectedItem="{Binding CurrentCulture}" Style="{DynamicResource ComboBox_BaseStyle}">
<ComboBox.ContextMenu>
<ContextMenu>
<MenuItem Command="{Binding OpenLocalTextCommand}" Header="{ll:Str 打开翻译文本}" />
</ContextMenu>
</ComboBox.ContextMenu>
</ComboBox>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel>
<Button MinWidth="150" x:Name="Button_OpenSettingEditor" Click="Button_OpenSettingEditor_Click"
Content="{ll:Str 打开设置编辑器}" FontSize="16" Style="{DynamicResource Button_BaseStyle}" />
<Button MinWidth="150" x:Name="Button_OpenSaveViewer" Click="Button_OpenSaveViewer_Click"
Content="{ll:Str 打开存档查看器}" FontSize="16" Style="{DynamicResource Button_BaseStyle}" />
</StackPanel>
<Button Grid.Row="1" Command="{Binding FirstStartFailedCommand}" Content="{ll:Str '第一次启动桌宠打不开?'}"
FontSize="16" Style="{DynamicResource LinkButtonStyle}" />
</Grid>
</Grid>
</pu:WindowX>

View File

@ -1,6 +1,8 @@
using HKW.HKWUtils;
using LinePutScript.Localization.WPF;
using Panuon.WPF.UI;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using VPet.Solution.ViewModels;
@ -28,7 +30,6 @@ public partial class MainWindow : WindowX
}
InitializeComponent();
this.SetViewModel<MainWindowVM>();
Closed += MainWindow_Closed;
}
@ -43,7 +44,7 @@ public partial class MainWindow : WindowX
SettingWindow.ShowOrActivate();
}
private void Button_OpenSaveEditor_Click(object sender, RoutedEventArgs e)
private void Button_OpenSaveViewer_Click(object sender, RoutedEventArgs e)
{
SaveWindow.ShowOrActivate();
}

View File

@ -87,13 +87,6 @@
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Save.StrengthDrink}" />
</DockPanel>
<DockPanel>
<Label
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str 哈希检查}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Save.HashChecked}" />
</DockPanel>
</StackPanel>
</ScrollViewer>
</Page>

View File

@ -77,6 +77,11 @@
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 游玩时长}"
IsReadOnly="True" />
<DataGridTextColumn
Binding="{Binding HashChecked}"
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 哈希}"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
</Grid>

View File

@ -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">
<Grid>
<StackPanel>
<TextBlock Background="{x:Null}" TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 自定义链接}" /><LineBreak />
<Run Text="{ll:Str '在自定栏添加快捷方式/网页/快捷键, 可以便携启动想要的功能'}" /><LineBreak />
<Run Text="{ll:Str '键盘快捷键编写方法请参考'}" /> <Hyperlink d:Click="sendkey_click">
<Run Text="{ll:Str '键盘快捷键 通用注解'}" />
</Hyperlink><LineBreak />
<Run Text="{ll:Str '右键进行排序/删除等操作'}" />
</TextBlock>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button
x:Name="btn_DIY"
Margin="4"
Padding="1"
d:Click="DIY_ADD_Click"
pu:ButtonHelper.CornerRadius="4"
Background="{DynamicResource SecondaryLight}"
Content="{ll:Str 添加新链接}" />
<Button
Grid.Column="1"
Margin="4"
Padding="1"
d:Click="DIY_Save_Click"
pu:ButtonHelper.CornerRadius="4"
Background="{DynamicResource SecondaryLight}"
Content="{ll:Str 保存设置}" />
</Grid>
<ScrollViewer>
<StackPanel x:Name="StackDIY" />
</ScrollViewer>
</StackPanel>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 自定义链接}" /><LineBreak />
<Run Text="{ll:Str '在自定栏添加快捷方式/网页/快捷键, 可以便携启动想要的功能'}" /><LineBreak />
<Run Text="{ll:Str '键盘快捷键编写方法请参考'}" /> <Hyperlink>
<Run Text="{ll:Str '键盘快捷键 通用注解'}" />
</Hyperlink><LineBreak />
</TextBlock>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="btn_DIY"
Padding="20,5,20,5"
Command="{Binding AddLinkCommand}"
Content="{ll:Str 添加新链接}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Grid.Column="1"
Padding="20,5,20,5"
d:Click="DIY_Save_Click"
Command="{Binding ClearLinksCommand}"
Content="{ll:Str 清空全部}"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<TextBox
Grid.Row="2"
pu:TextBoxHelper.Watermark="{ll:Str 搜索名称}"
Style="{DynamicResource StandardTextBoxStyle}"
Text="{Binding SearchLink, UpdateSourceTrigger=PropertyChanged}" />
<DataGrid
Grid.Row="3"
d:ItemsSource="{d:SampleData ItemCount=10}"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding ShowLinks}"
VerticalScrollBarVisibility="Auto">
<DataGrid.RowStyle>
<Style BasedOn="{StaticResource {x:Type DataGridRow}}" TargetType="DataGridRow">
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Page}}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}">
<MenuItem
Command="{Binding PlacementTarget.Tag.RemoveLinkCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 删除}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.RowStyle>
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
EditingElementStyle="{DynamicResource TextBox_LeftCenter}"
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 名称}" />
<DataGridTextColumn
Binding="{Binding Link, UpdateSourceTrigger=PropertyChanged}"
EditingElementStyle="{DynamicResource TextBox_LeftCenter}"
ElementStyle="{DynamicResource TextBlock_LeftCenter}"
Header="{ll:Str 链接}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Page>

View File

@ -13,107 +13,71 @@
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<ScrollViewer>
<StackPanel>
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 自动超模MOD优化}" /><LineBreak />
<Run Text="{ll:Str '对于超模内容,游戏会自动计算合理价格\&#13;如果未使用任何超模数据,数据菜单栏将会显示图标方便您进行炫耀数据'}" />
</TextBlock>
<pu:Switch
x:Name="swAutoCal"
Grid.Column="2"
Margin="20,0,0,0"
HorizontalAlignment="Left"
d:Checked="swAutoCal_Checked"
d:Unchecked="swAutoCal_Checked"
Background="Transparent"
BorderBrush="{DynamicResource PrimaryDark}"
BoxHeight="18"
BoxWidth="35"
CheckedBackground="{DynamicResource Primary}"
CheckedBorderBrush="{DynamicResource Primary}"
CheckedToggleBrush="{DynamicResource DARKPrimaryText}"
Content="{ll:Str '自动计算合理价格'}"
ToggleBrush="{DynamicResource PrimaryDark}"
ToggleShadowColor="{x:Null}"
ToggleSize="14"
ToolTip="{ll:Str '该选项重启后生效'}" />
<TextBlock
Margin="0,20,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
FontSize="13"
TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 诊断与反馈}" /> <LineBreak />
<Run Text="{ll:Str '选择要发送给 LBGame 的诊断数据,诊断数据用于保护和及时更新 虚拟桌宠模拟器, 解决问题并改进产品.'}" /><LineBreak />
<Run Text="{ll:Str '无论选择哪个选项,游戏都可以安全正常地运行.'}" /> <Hyperlink d:Click="hyper_moreInfo">
<Run Text="{ll:Str 获取有关这些设置的更多信息}" />
</Hyperlink>
<LineBreak /> <Run FontWeight="Bold" Text="{ll:Str '当前存档Hash验证信息'}" />
:<Run
x:Name="RHashCheck"
FontWeight="Bold"
Text="通过" />
</TextBlock>
<RadioButton
x:Name="RBDiagnosisYES"
Margin="10,10,10,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Checked="RBDiagnosisYES_Checked"
Content="{ll:Str '发送诊断数据: 发送游戏存档, 包括饱腹,状态等各种游戏内\&#13;数据. 可能会包括该游戏内存和CPU使用情况'}"
GroupName="diagnosis"
Style="{DynamicResource StandardRadioButtonStyle}" />
<RadioButton
x:Name="RBDiagnosisNO"
Margin="10,10,10,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Checked="RBDiagnosisNO_Checked"
Content="{ll:Str '不发送诊断数据: 适用于启用修改器,修改过游戏数据等不\&#13;符合分析数据条件. 或不希望提供游戏数据的玩家'}"
GroupName="diagnosis"
IsChecked="True"
Style="{DynamicResource StandardRadioButtonStyle}" />
<TextBlock
Margin="0,15,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{ll:Str 反馈频率}" /><LineBreak />
<Run Text="{ll:Str 'VOS 应寻求我反馈按以下频率'}" />
</TextBlock>
<StackPanel>
<TextBlock
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 自动超模MOD优化}" /><LineBreak />
<Run Text="{ll:Str '对于超模内容,游戏会自动计算合理价格\&#13;如果未使用任何超模数据,数据菜单栏将会显示图标方便您进行炫耀数据'}" />
</TextBlock>
<pu:Switch
x:Name="swAutoCal"
Grid.Column="2"
Content="{ll:Str '自动计算合理价格'}"
IsChecked="{Binding DiagnosticSetting.AutoCal}"
Style="{DynamicResource Switch_BaseStyle}" />
<TextBlock
Margin="0,20,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
FontSize="13"
TextWrapping="Wrap">
<Run
FontSize="18"
FontWeight="Bold"
Text="{ll:Str 诊断与反馈}" /> <LineBreak />
<Run Text="{ll:Str '选择要发送给 LBGame 的诊断数据,诊断数据用于保护和及时更新 虚拟桌宠模拟器, 解决问题并改进产品.'}" /><LineBreak />
<Run Text="{ll:Str '无论选择哪个选项,游戏都可以安全正常地运行.'}" /> <Hyperlink d:Click="hyper_moreInfo">
<Run Text="{ll:Str 获取有关这些设置的更多信息}" />
</Hyperlink>
<LineBreak /> <Run FontWeight="Bold" Text="{ll:Str '当前存档Hash验证信息'}" />
:<Run
x:Name="RHashCheck"
FontWeight="Bold"
Text="通过" />
</TextBlock>
<pu:Switch
x:Name="RBDiagnosisYES"
CheckedContent="{ll:Str '发送诊断数据: 发送游戏存档, 包括饱腹,状态等各种游戏内\&#13;数据. 可能会包括该游戏内存和CPU使用情况'}"
Content="{ll:Str '不发送诊断数据: 适用于启用修改器,修改过游戏数据等不\&#13;符合分析数据条件. 或不希望提供游戏数据的玩家'}"
IsChecked="{Binding DiagnosticSetting.Diagnosis}"
Style="{DynamicResource Switch_BaseStyle}" />
<StackPanel>
<TextBlock
Margin="0,15,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{ll:Str 反馈频率}" /><LineBreak />
<Run Text="{ll:Str 'VOS 应寻求我反馈按以下频率'}" />
</TextBlock>
<StackPanel Orientation="Horizontal">
<ComboBox
x:Name="CBDiagnosis"
Width="200"
Margin="10,5,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:SelectionChanged="CBDiagnosis_SelectionChanged"
IsEnabled="False"
SelectedIndex="1"
Style="{DynamicResource StandardComboBoxStyle}">
<ComboBoxItem Content="{ll:Str '每 两百 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 五百 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 一千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 两千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 五千 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 一万 周期一次'}" />
<ComboBoxItem Content="{ll:Str '每 两万 周期一次'}" />
</ComboBox>
ItemsSource="{Binding DiagnosticSetting.DiagnosisIntervals}"
SelectedItem="{Binding DiagnosticSetting.DiagnosisInterval}"
Style="{DynamicResource ComboBox_BaseStyle}" />
<Label Content="{ll:Str 每周期一次}" Style="{DynamicResource Label_BaseStyle}" />
</StackPanel>
</ScrollViewer>
</Grid>
</StackPanel>
</StackPanel>
</Page>

View File

@ -3,233 +3,231 @@
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"
xmlns:pu="https://opensource.panuon.com/wpf-ui"
xmlns:vm="clr-namespace:VPet.Solution.ViewModels.SettingEditor"
Title="ModSettingsPage"
d:DataContext="{d:DesignInstance Type=vm:GraphicsSettingPageVM}"
d:DataContext="{d:DesignInstance Type=vm:ModSettingPageVM}"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="15" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="120" />
<ColumnDefinition Width="10" />
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>
<ListBox
x:Name="ListMod"
VerticalAlignment="Top"
d:SelectionChanged="ListMod_SelectionChanged"
Background="Transparent"
BorderThickness="0"
SelectionMode="Single"
Style="{DynamicResource SideMenuListBoxStyle}" />
<StackPanel Grid.Column="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox
pu:TextBoxHelper.Watermark="{ll:Str 搜索模组}"
Style="{DynamicResource StandardTextBoxStyle}"
Text="{Binding SearchMod, UpdateSourceTrigger=PropertyChanged}" />
<DataGrid
x:Name="DataGrid_Mods"
Grid.Row="1"
AutoGenerateColumns="False"
CanUserAddRows="False"
ItemsSource="{Binding ShowMods}"
SelectedItem="{Binding CurrentModMoel}">
<DataGrid.Columns>
<DataGridTextColumn
Binding="{Binding Name}"
ElementStyle="{DynamicResource TextBlock_BaseStyle}"
Header="{ll:Str 名称}"
IsReadOnly="True" />
<DataGridTextColumn
Binding="{Binding State}"
ElementStyle="{DynamicResource TextBlock_BaseStyle}"
Header="{ll:Str 状态}"
IsReadOnly="True" />
</DataGrid.Columns>
</DataGrid>
<Button
Grid.Row="2"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ClearFailModsCommand}"
Content="{ll:Str 清除失效模组}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Grid.Row="3"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ClearModsCommand}"
Content="{ll:Str 清除全部模组}"
Style="{DynamicResource Button_BaseStyle}" />
</Grid>
<Grid
Grid.Column="2"
d:DataContext="{Binding ModSetting.Mods[0]}"
DataContext="{Binding SelectedItem, ElementName=DataGrid_Mods}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="7" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image
x:Name="ImageMOD"
Width="120"
Height="120"
Margin="0,5,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Width="150"
Height="150"
Source="{Binding Image}"
Stretch="Fill" />
<StackPanel Grid.Column="2">
<Label
x:Name="LabelModName"
Margin="-5,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
Content="Core"
FontSize="20"
FontWeight="Bold"
Foreground="{DynamicResource PrimaryText}" />
<TextBlock Margin="0,0,0,0" TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{ll:Str '模组作者: '}" /><LineBreak />
<Run x:Name="runMODAuthor" Text="LorisYounger" />
<LineBreak /><Run FontWeight="Bold" Text="{ll:Str '模组版本: '}" /><Run x:Name="runMODVer" Text="1.0" />
<LineBreak /><Run FontWeight="Bold" Text="{ll:Str '游戏版本: '}" /><Run x:Name="runMODGameVer" Text="1.0" />
</TextBlock>
</StackPanel>
<ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组名称:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Name}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '作者:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding Author}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组版本:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding ModVersion}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '游戏版本:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding GameVersion}" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label
Margin="10,0,10,0"
h:ElementHelper.UniformMinWidthGroup="A"
Content="{ll:Str '模组路径:'}"
Style="{DynamicResource Label_BaseStyle}" />
<TextBlock Style="{DynamicResource TextBlock_LeftCenter}" Text="{Binding ModPath}" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
<Label
Margin="-5,0,0,0"
Padding="5,5,5,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str MOD介绍}"
FontSize="18"
FontWeight="Bold" />
<ScrollViewer
Height="80"
HorizontalAlignment="Left"
VerticalAlignment="Top"
pu:ScrollViewerHelper.ScrollBarThickness="10"
VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="GameInfo"
VerticalAlignment="Top"
FontSize="14"
Text="这里是MOD的介绍内容,你的介绍就是你的介绍&#xA;"
TextWrapping="Wrap" />
</ScrollViewer>
<Grid>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
HorizontalAlignment="Left"
Content="{ll:Str MOD介绍}"
FontSize="18"
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="GameInfo"
FontSize="14"
Style="{DynamicResource TextBlock_Wrap}"
Text="{Binding Description}" />
</ScrollViewer>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Margin="-5,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Background="{x:Null}"
Content="{ll:Str 内容}"
FontSize="18"
FontWeight="Bold" />
<ScrollViewer
Height="140"
Margin="0,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
pu:ScrollViewerHelper.ScrollBarThickness="10"
VerticalScrollBarVisibility="Auto">
<TextBlock
x:Name="GameHave"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="14"
Text="该mod有许多功能&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1&#xA;比如说功能1"
TextWrapping="Wrap" />
</ScrollViewer>
</StackPanel>
<StackPanel Grid.Column="1">
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<ItemsControl Grid.Row="1" ItemsSource="{Binding Tags}" />
</Grid>
<Grid
Grid.Column="1"
h:ElementHelper.IsEnabled="{Binding IsEnabled, Converter={StaticResource NullToFalse}}"
IsEnabled="False">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Label
Margin="-5,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="{x:Null}"
Content="{ll:Str 操作}"
FontSize="18"
FontWeight="Bold" />
<TextBlock
x:Name="ButtonOpenModFolder"
Margin="0,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonOpenModFolder_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '所在文件夹'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonEnable"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonEnable_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '启用该模组'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonDisEnable"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonDisEnable_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str '停用该模组'}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonPublish"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonPublish_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="DimGray"
Text="{ll:Str 更新至Steam}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<TextBlock
x:Name="ButtonSteam"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonSteam_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="DimGray"
Text="{ll:Str 创意工坊页面}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<ProgressBar
x:Name="ProgressBarUpload"
Height="30"
Margin="0,2,0,0"
VerticalAlignment="Top"
pu:ProgressBarHelper.CornerRadius="2"
pu:ProgressBarHelper.IsPercentVisible="True"
Background="{DynamicResource Primary}"
BorderBrush="{DynamicResource PrimaryDarker}"
BorderThickness="2"
Foreground="{DynamicResource DARKPrimary}"
Visibility="Collapsed"
Value="60" />
<TextBlock
x:Name="ButtonSetting"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonSetting_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="{DynamicResource DARKPrimaryDarker}"
Text="{ll:Str MOD设置}"
TextDecorations="Underline"
TextWrapping="Wrap" />
<Button
x:Name="ButtonAllow"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:Click="ButtonAllow_Click"
Background="#FFFF2C2C"
Content="{ll:Str 启用代码插件}"
FontSize="12"
Foreground="White"
ToolTip="{ll:Str '启用该模组的代码内容,不能保证系统安全性'}" />
</StackPanel>
<Button
x:Name="ButtonRestart"
Grid.ColumnSpan="2"
Margin="0,2,0,0"
VerticalAlignment="Bottom"
d:Click="ButtonRestart_Click"
Background="{DynamicResource DARKPrimary}"
Content="{ll:Str 重启软件以应用更改}"
Foreground="{DynamicResource DARKPrimaryText}"
Visibility="Collapsed" />
FontWeight="Bold"
Style="{DynamicResource Label_BaseStyle}" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<pu:Switch
Content="{ll:Str 启用模组}"
IsChecked="{Binding IsEnabled}"
Style="{DynamicResource Switch_BaseStyle}" />
<pu:Switch
Content="{ll:Str 启用模组代码}"
IsChecked="{Binding IsPass}"
IsEnabled="{Binding IsMsg}"
Style="{DynamicResource Switch_BaseStyle}" />
</StackPanel>
<StackPanel Grid.Column="1">
<Button
HorizontalAlignment="Left"
Command="{Binding DataContext.OpenModPathCommand, RelativeSource={RelativeSource AncestorType=Page}}"
CommandParameter="{Binding}"
Content="{ll:Str '打开所在文件夹'}"
Style="{DynamicResource Button_BaseStyle}" />
<!--<TextBlock
x:Name="ButtonPublish"
Margin="0,2,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
d:MouseDown="ButtonPublish_MouseDown"
Cursor="Hand"
FontSize="14"
Foreground="DimGray"
Text="{ll:Str 更新至Steam}"
TextDecorations="Underline"
TextWrapping="Wrap" />-->
<Button
x:Name="ButtonSteam"
HorizontalAlignment="Left"
Command="{Binding DataContext.OpenSteamCommunityCommand, RelativeSource={RelativeSource AncestorType=Page}}"
CommandParameter="{Binding}"
Content="{ll:Str 打开创意工坊页面}"
Style="{DynamicResource Button_BaseStyle}" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Page>

View File

@ -27,7 +27,6 @@
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox
pu:TextBoxHelper.Watermark="{ll:Str 搜索设置}"
@ -45,63 +44,87 @@
<Setter Property="Tag" Value="{Binding DataContext, RelativeSource={RelativeSource AncestorType=Window}}" />
<Setter Property="Content" Value="{Binding Name}" />
<Setter Property="ToolTip" Value="{Binding FilePath}" />
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Mode=Self}}">
<MenuItem
Command="{Binding PlacementTarget.Tag.OpenFileCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 打开文件}" />
<MenuItem
Command="{Binding PlacementTarget.Tag.OpenFileInExplorerCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 从资源管理器打开文件}" />
<MenuItem
Command="{Binding PlacementTarget.Tag.SaveSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 保存}" />
<MenuItem
Command="{Binding PlacementTarget.Tag.ResetSettingCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"
CommandParameter="{Binding}"
Header="{ll:Str 重置}" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button
Grid.Row="3"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding SaveAllSettingCommand}"
Content="{ll:Str 全部保存}"
Style="{DynamicResource Button_BaseStyle}" />
<StackPanel Grid.Row="2">
<Button
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ResetAllSettingCommand}"
Content="{ll:Str 全部重置}"
Style="{DynamicResource Button_BaseStyle}" />
<Button
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding SaveAllSettingCommand}"
Content="{ll:Str 全部保存}"
Style="{DynamicResource Button_BaseStyle}" />
</StackPanel>
</Grid>
<Grid Grid.Column="1" IsEnabled="{Binding SelectedItem, ElementName=ListBox_Saves, Converter={StaticResource NullToFalse}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ListBox x:Name="ListBox_Pages" Style="{DynamicResource SideMenuListBoxStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem x:Name="ListBoxItem_GraphicsSettings" Content="{ll:Str 图形}" />
<ListBoxItem x:Name="ListBoxItem_SystemSettings" Content="{ll:Str 系统}" />
<ListBoxItem x:Name="ListBoxItem_InteractiveSettings" Content="{ll:Str 互动}" />
<ListBoxItem x:Name="ListBoxItem_CustomizedSettings" Content="{ll:Str 自定}" />
<ListBoxItem x:Name="ListBoxItem_DiagnosticSettings" Content="{ll:Str 诊断}" />
<ListBoxItem x:Name="ListBoxItem_ModSettings" Content="{ll:Str Mod管理}" />
</ListBox>
<Frame
x:Name="Frame_Main"
Grid.Row="1"
Content="{Binding SelectedItem.Tag, ElementName=ListBox_Pages}"
ContentRendered="Frame_Main_ContentRendered"
NavigationUIVisibility="Hidden" />
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ListBox x:Name="ListBox_Pages" Style="{DynamicResource SideMenuListBoxStyle}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem x:Name="ListBoxItem_GraphicsSettings" Content="{ll:Str 图形}" />
<ListBoxItem x:Name="ListBoxItem_SystemSettings" Content="{ll:Str 系统}" />
<ListBoxItem x:Name="ListBoxItem_InteractiveSettings" Content="{ll:Str 互动}" />
<ListBoxItem x:Name="ListBoxItem_CustomizedSettings" Content="{ll:Str 自定}" />
<ListBoxItem x:Name="ListBoxItem_DiagnosticSettings" Content="{ll:Str 诊断}" />
<ListBoxItem x:Name="ListBoxItem_ModSettings" Content="{ll:Str Mod管理}" />
</ListBox>
<Frame
x:Name="Frame_Main"
Grid.Row="1"
Content="{Binding SelectedItem.Tag, ElementName=ListBox_Pages}"
ContentRendered="Frame_Main_ContentRendered"
NavigationUIVisibility="Hidden" />
</Grid>
<StackPanel Grid.Column="1" MinWidth="100">
<Button
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding OpenFileCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ListBox_Saves}"
Content="{ll:Str 打开文件}"
Style="{StaticResource Button_BaseStyle}" />
<Button
Grid.Column="1"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding OpenFileInExplorerCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ListBox_Saves}"
Content="{ll:Str 从资源管理器打开文件}"
Style="{StaticResource Button_BaseStyle}" />
<Button
Grid.Column="2"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding SaveSettingCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ListBox_Saves}"
Content="{ll:Str 保存}"
Style="{StaticResource Button_BaseStyle}" />
<Button
Grid.Column="3"
Margin="0"
HorizontalAlignment="Stretch"
Command="{Binding ResetSettingCommand}"
CommandParameter="{Binding SelectedItem, ElementName=ListBox_Saves}"
Content="{ll:Str 重置}"
Style="{StaticResource Button_BaseStyle}" />
</StackPanel>
<!--<TabControl
x:Name="MainTab"
Grid.Column="1"

View File

@ -3,6 +3,6 @@
<package id="FastMember" version="1.5.0" targetFramework="net462" />
<package id="LinePutScript" version="1.9.2" targetFramework="net462" />
<package id="LinePutScript.Localization.WPF" version="1.0.6" targetFramework="net462" />
<package id="Panuon.WPF" version="1.0.2" targetFramework="net462" />
<package id="Panuon.WPF.UI" version="1.1.15.8" targetFramework="net462" />
<package id="Panuon.WPF" version="1.0.3" targetFramework="net462" />
<package id="Panuon.WPF.UI" version="1.1.16.5" targetFramework="net462" />
</packages>