Merge branch 'DGP-Studio:main' into main

This commit is contained in:
Xhichn
2023-03-15 23:40:21 +08:00
committed by GitHub
35 changed files with 220 additions and 153 deletions

View File

@@ -31,6 +31,11 @@ internal sealed class SettingEntry
/// </summary>
public const string SystemBackdropType = "SystemBackdropType";
/// <summary>
/// 启用高级功能
/// </summary>
public const string IsAdvancedLaunchOptionsEnabled = "IsAdvancedLaunchOptionsEnabled";
/// <summary>
/// 实时便笺刷新时间
/// </summary>

View File

@@ -1,13 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.ViewModel.Complex;
using Snap.Hutao.ViewModel.GachaLog;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.Model.Metadata.Avatar;
@@ -36,6 +36,7 @@ internal partial class Avatar : IStatisticsItemSource, ISummaryItemSource, IName
/// <summary>
/// 最大等级
/// </summary>
[SuppressMessage("", "CA1822")]
public int MaxLevel { get => 90; }
/// <inheritdoc/>

View File

@@ -3,6 +3,7 @@
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.ViewModel.Cultivation;
using System.Collections.Immutable;
namespace Snap.Hutao.Model.Metadata.Item;
@@ -81,6 +82,7 @@ internal sealed class Material : Display
return true;
}
// TODO: Currently only support CN
return TypeDescription switch
{
"角色与武器培养素材" => true,
@@ -114,23 +116,23 @@ internal sealed class Material : Display
/// 获取物品对应的 DaysOfWeek
/// </summary>
/// <returns>DaysOfWeek</returns>
public Binding.Cultivation.DaysOfWeek GetDaysOfWeek()
public DaysOfWeek GetDaysOfWeek()
{
if (MondayThursdayItems.Contains(Id))
{
return Binding.Cultivation.DaysOfWeek.MondayAndThursday;
return DaysOfWeek.MondayAndThursday;
}
if (TuesdayFridayItems.Contains(Id))
{
return Binding.Cultivation.DaysOfWeek.TuesdayAndFriday;
return DaysOfWeek.TuesdayAndFriday;
}
if (WednesdaySaturdayItems.Contains(Id))
{
return Binding.Cultivation.DaysOfWeek.WednesdayAndSaturday;
return DaysOfWeek.WednesdayAndSaturday;
}
return Binding.Cultivation.DaysOfWeek.Any;
return DaysOfWeek.Any;
}
}

View File

@@ -3561,6 +3561,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 启用「启动游戏-高级功能」的任意功能 您需要在设置里解锁它 的本地化字符串。
/// </summary>
internal static string ViewPageLaunchGameAdvancedFeatureElevationHint {
get {
return ResourceManager.GetString("ViewPageLaunchGameAdvancedFeatureElevationHint", resourceCulture);
}
}
/// <summary>
/// 查找类似 高级功能 的本地化字符串。
/// </summary>
@@ -4191,6 +4200,33 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 在完整阅读原神和胡桃工具箱用户协议后,我选择启用「启动游戏-高级功能」 的本地化字符串。
/// </summary>
internal static string ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription {
get {
return ResourceManager.GetString("ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription", resourceCulture);
}
}
/// <summary>
/// 查找类似 启动高级功能 的本地化字符串。
/// </summary>
internal static string ViewPageSettingIsAdvancedLaunchOptionsEnabledHeader {
get {
return ResourceManager.GetString("ViewPageSettingIsAdvancedLaunchOptionsEnabledHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 您解锁了「启动游戏-高级功能」!其含有潜在违反原神服务条款的风险,一旦启用,您将咨询承担可能的后果。慎重选择! 的本地化字符串。
/// </summary>
internal static string ViewPageSettingFeaturesDangerousHint {
get {
return ResourceManager.GetString("ViewPageSettingFeaturesDangerousHint", resourceCulture);
}
}
/// <summary>
/// 查找类似 Github 上反馈的问题会优先处理 的本地化字符串。
/// </summary>

View File

@@ -1284,6 +1284,9 @@
<data name="ViewPageLaunchGameAction" xml:space="preserve">
<value>启动游戏</value>
</data>
<data name="ViewPageLaunchGameAdvancedFeatureElevationHint" xml:space="preserve">
<value>启用「启动游戏-高级功能」的任意功能 您需要在设置里解锁它</value>
</data>
<data name="ViewPageLaunchGameAdvanceHeader" xml:space="preserve">
<value>高级功能</value>
</data>
@@ -1494,6 +1497,15 @@
<data name="ViewPageSettingEmptyHistoryVisibleOn" xml:space="preserve">
<value>显示</value>
</data>
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription" xml:space="preserve">
<value>在完整阅读原神和胡桃工具箱用户协议后,我选择启用「启动游戏-高级功能」</value>
</data>
<data name="ViewPageSettingIsAdvancedLaunchOptionsEnabledHeader" xml:space="preserve">
<value>启动高级功能</value>
</data>
<data name="ViewPageSettingFeaturesDangerousHint" xml:space="preserve">
<value>您解锁了「启动游戏-高级功能」!其含有潜在违反原神服务条款的风险,一旦启用,您将咨询承担可能的后果。慎重选择!</value>
</data>
<data name="ViewPageSettingFeedbackDescription" xml:space="preserve">
<value>Github 上反馈的问题会优先处理</value>
</data>

View File

@@ -6,6 +6,7 @@ using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using System.Globalization;
@@ -24,6 +25,7 @@ internal sealed class AppOptions : ObservableObject, IOptions<AppOptions>
private bool? isEmptyHistoryWishVisible;
private Core.Windowing.BackdropType? backdropType;
private CultureInfo? currentCulture;
private bool? isAdvancedLaunchOptionsEnabled;
/// <summary>
/// 构造一个新的应用程序选项
@@ -171,6 +173,40 @@ internal sealed class AppOptions : ObservableObject, IOptions<AppOptions>
}
}
/// <summary>
/// 是否启用高级功能
/// </summary>
public bool IsAdvancedLaunchOptionsEnabled
{
get
{
if (isAdvancedLaunchOptionsEnabled == null)
{
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string? value = appDbContext.Settings.SingleOrDefault(e => e.Key == SettingEntry.IsAdvancedLaunchOptionsEnabled)?.Value;
isAdvancedLaunchOptionsEnabled = value != null && bool.Parse(value);
}
}
return isAdvancedLaunchOptionsEnabled.Value;
}
set
{
if (SetProperty(ref isAdvancedLaunchOptionsEnabled, value))
{
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
appDbContext.Settings.ExecuteDeleteWhere(e => e.Key == SettingEntry.IsAdvancedLaunchOptionsEnabled);
appDbContext.Settings.AddAndSave(new(SettingEntry.IsAdvancedLaunchOptionsEnabled, value.ToString()));
}
}
}
}
/// <inheritdoc/>
public AppOptions Value { get => this; }
}

View File

@@ -13,11 +13,8 @@ using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Metadata;
using Snap.Hutao.ViewModel.Cultivation;
using System.Collections.ObjectModel;
using BindingCultivateEntry = Snap.Hutao.Model.Binding.Cultivation.CultivateEntryView;
using BindingCultivateItem = Snap.Hutao.Model.Binding.Cultivation.CultivateItem;
using BindingInventoryItem = Snap.Hutao.Model.Binding.Inventory.InventoryItem;
using BindingStatisticsItem = Snap.Hutao.Model.Binding.Cultivation.StatisticsCultivateItem;
namespace Snap.Hutao.Service.Cultivation;
@@ -64,7 +61,7 @@ internal sealed class CultivationService : ICultivationService
try
{
Current ??= projects.SingleOrDefault(proj => proj.IsSelected);
Current ??= projects.SelectedOrDefault();
}
catch (DbUpdateConcurrencyException ex)
{
@@ -129,7 +126,7 @@ internal sealed class CultivationService : ICultivationService
}
/// <inheritdoc/>
public List<BindingInventoryItem> GetInventoryItems(CultivateProject cultivateProject, List<Material> metadata, ICommand saveCommand)
public List<InventoryItemView> GetInventoryItems(CultivateProject cultivateProject, List<Material> metadata, ICommand saveCommand)
{
Guid projectId = cultivateProject.InnerId;
using (IServiceScope scope = scopeFactory.CreateScope())
@@ -139,7 +136,7 @@ internal sealed class CultivationService : ICultivationService
.Where(a => a.ProjectId == projectId)
.ToList();
List<BindingInventoryItem> results = new();
List<InventoryItemView> results = new();
foreach (Material meta in metadata.Where(m => m.IsInventoryItem()).OrderBy(m => m.Id))
{
InventoryItem entity = entities.SingleOrDefault(e => e.ItemId == meta.Id) ?? InventoryItem.Create(projectId, meta.Id);
@@ -151,7 +148,7 @@ internal sealed class CultivationService : ICultivationService
}
/// <inheritdoc/>
public async Task<ObservableCollection<BindingCultivateEntry>> GetCultivateEntriesAsync(CultivateProject cultivateProject)
public async Task<ObservableCollection<CultivateEntryView>> GetCultivateEntriesAsync(CultivateProject cultivateProject)
{
await ThreadHelper.SwitchToBackgroundAsync();
using (IServiceScope scope = scopeFactory.CreateScope())
@@ -163,7 +160,7 @@ internal sealed class CultivationService : ICultivationService
Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap = await metadataService.GetIdToAvatarMapAsync().ConfigureAwait(false);
Dictionary<WeaponId, Model.Metadata.Weapon.Weapon> idWeaponMap = await metadataService.GetIdToWeaponMapAsync().ConfigureAwait(false);
List<BindingCultivateEntry> results = new();
List<CultivateEntryView> results = new();
List<CultivateEntry> entries = await appDbContext.CultivateEntries
.Where(e => e.ProjectId == cultivateProject.InnerId)
.ToListAsync()
@@ -173,7 +170,7 @@ internal sealed class CultivationService : ICultivationService
{
Guid entryId = entry.InnerId;
List<BindingCultivateItem> resultItems = new();
List<CultivateItemView> resultItems = new();
foreach (CultivateItem item in await GetEntryItemsAsync(appDbContext, entryId).ConfigureAwait(false))
{
@@ -197,11 +194,11 @@ internal sealed class CultivationService : ICultivationService
}
/// <inheritdoc/>
public async Task<ObservableCollection<BindingStatisticsItem>> GetStatisticsCultivateItemCollectionAsync(CultivateProject cultivateProject, CancellationToken token)
public async Task<ObservableCollection<StatisticsCultivateItem>> GetStatisticsCultivateItemCollectionAsync(CultivateProject cultivateProject, CancellationToken token)
{
using (IServiceScope scope = scopeFactory.CreateScope())
{
List<BindingStatisticsItem> resultItems = new();
List<StatisticsCultivateItem> resultItems = new();
AppDbContext appDbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
List<Material> materials = await scope.ServiceProvider
@@ -222,7 +219,7 @@ internal sealed class CultivationService : ICultivationService
continue;
}
if (resultItems.SingleOrDefault(i => i.Inner.Id == item.ItemId) is BindingStatisticsItem existedItem)
if (resultItems.SingleOrDefault(i => i.Inner.Id == item.ItemId) is StatisticsCultivateItem existedItem)
{
existedItem.Count += item.Count;
}
@@ -237,7 +234,7 @@ internal sealed class CultivationService : ICultivationService
foreach (InventoryItem inventoryItem in await GetProjectInventoryAsync(appDbContext, projectId).ConfigureAwait(false))
{
if (resultItems.SingleOrDefault(i => i.Inner.Id == inventoryItem.ItemId) is BindingStatisticsItem existedItem)
if (resultItems.SingleOrDefault(i => i.Inner.Id == inventoryItem.ItemId) is StatisticsCultivateItem existedItem)
{
existedItem.TotalCount += inventoryItem.Count;
}
@@ -264,7 +261,7 @@ internal sealed class CultivationService : ICultivationService
}
/// <inheritdoc/>
public void SaveInventoryItem(BindingInventoryItem item)
public void SaveInventoryItem(InventoryItemView item)
{
using (IServiceScope scope = scopeFactory.CreateScope())
{
@@ -295,7 +292,7 @@ internal sealed class CultivationService : ICultivationService
try
{
Current ??= appDbContext.CultivateProjects.AsNoTracking().SingleOrDefault(proj => proj.IsSelected);
Current ??= appDbContext.CultivateProjects.AsNoTracking().SelectedOrDefault();
}
catch (InvalidOperationException ex)
{

View File

@@ -1,10 +1,10 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.ViewModel.Cultivation;
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
using System.Collections.ObjectModel;
@@ -35,7 +35,7 @@ internal interface ICultivationService
/// <param name="metadata">元数据</param>
/// <param name="saveCommand">保存命令</param>
/// <returns>物品列表</returns>
List<Model.Binding.Inventory.InventoryItem> GetInventoryItems(CultivateProject cultivateProject, List<Material> metadata, ICommand saveCommand);
List<InventoryItemView> GetInventoryItems(CultivateProject cultivateProject, List<Material> metadata, ICommand saveCommand);
/// <summary>
/// 获取用于绑定的项目集合
@@ -84,7 +84,7 @@ internal interface ICultivationService
/// 保存单个物品
/// </summary>
/// <param name="item">物品</param>
void SaveInventoryItem(Model.Binding.Inventory.InventoryItem item);
void SaveInventoryItem(InventoryItemView item);
/// <summary>
/// 异步尝试添加新的项目

View File

@@ -301,15 +301,16 @@ internal sealed class GameService : IGameService
try
{
Interlocked.Increment(ref runningGamesCounter);
bool isElevated = Activation.GetElevated();
game.Start();
if (isElevated && launchOptions.MultipleInstances)
bool isAdvancedOptionsAllowed = Activation.GetElevated() && appOptions.IsAdvancedLaunchOptionsEnabled;
if (isAdvancedOptionsAllowed && launchOptions.MultipleInstances)
{
await ProcessInterop.DisableProtectionAsync(game, gamePath).ConfigureAwait(false);
ProcessInterop.DisableProtection(game, gamePath);
}
if (isElevated && launchOptions.UnlockFps)
if (isAdvancedOptionsAllowed && launchOptions.UnlockFps)
{
await ProcessInterop.UnlockFpsAsync(game, launchOptions).ConfigureAwait(false);
}

View File

@@ -2,11 +2,9 @@
// Licensed under the MIT license.
using Snap.Hutao.Core;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Service.Game.Unlocker;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace Snap.Hutao.Service.Game;
@@ -69,21 +67,17 @@ internal static class ProcessInterop
/// <param name="game">游戏进程</param>
/// <param name="gamePath">游戏路径</param>
/// <returns>是否禁用成功</returns>
public static async Task<bool> DisableProtectionAsync(Process game, string gamePath)
public static bool DisableProtection(Process game, string gamePath)
{
string? gameFolder = Path.GetDirectoryName(gamePath);
if (!string.IsNullOrEmpty(gameFolder))
{
string pbasePath = Path.Combine(gameFolder, "mhypbase.dll");
SafeHandle handle = File.OpenHandle(pbasePath, share: FileShare.None);
while (true) {
if (game.MainWindowHandle != nint.Zero) {
handle.Close();
break;
}
await Task.Delay(100).ConfigureAwait(false);
string mhypbaseDll = Path.Combine(gameFolder, "mhypbase.dll");
using (File.OpenHandle(mhypbaseDll, share: FileShare.None))
{
SpinWait.SpinUntil(() => game.MainWindowHandle != 0);
return true;
}
return true;
}
return false;

View File

@@ -4,7 +4,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Control;
using Snap.Hutao.Model.Binding.BaseValue;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.View.Control;

View File

@@ -251,12 +251,18 @@
</wsc:Setting>
</wsc:SettingsGroup>
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding IsElevated}">
<wsc:SettingsGroup Header="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHeader}" IsEnabled="{Binding AppOptions.IsAdvancedLaunchOptionsEnabled}">
<InfoBar
IsClosable="False"
IsOpen="{Binding IsElevated}"
IsOpen="{Binding AppOptions.IsAdvancedLaunchOptionsEnabled}"
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvanceHint}"
Severity="Error"/>
<InfoBar
Margin="0,2,0,0"
IsClosable="False"
IsOpen="{Binding AppOptions.IsAdvancedLaunchOptionsEnabled, Converter={StaticResource BoolNegationConverter}}"
Message="{shcm:ResourceString Name=ViewPageLaunchGameAdvancedFeatureElevationHint}"
Severity="Warning"/>
<wsc:Setting
Description="{shcm:ResourceString Name=ViewPageLaunchGameMultipleInstancesDescription}"
Header="{shcm:ResourceString Name=ViewPageLaunchGameMultipleInstancesHeader}"

View File

@@ -209,6 +209,32 @@
</wsc:SettingsGroup>
<wsc:SettingsGroup Foreground="{ThemeResource SystemFillColorCriticalBrush}" Header="{shcm:ResourceString Name=ViewPageSettingDangerousHeader}">
<InfoBar
IsClosable="False"
IsOpen="{Binding Options.IsAdvancedLaunchOptionsEnabled}"
Message="{shcm:ResourceString Name=ViewPageSettingFeaturesDangerousHint}"
Severity="Error"/>
<InfoBar
Margin="0,2,0,0"
IsClosable="False"
IsOpen="{Binding IsElevated, Converter={StaticResource BoolNegationConverter}}"
Message="{shcm:ResourceString Name=ViewPageLaunchGameElevationHint}"
Severity="Warning"/>
<wsc:Setting
Background="{StaticResource SystemFillColorCriticalBackgroundBrush}"
Description="{shcm:ResourceString Name=ViewPageSettingIsAdvancedLaunchOptionsEnabledDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingIsAdvancedLaunchOptionsEnabledHeader}"
Icon="&#xE730;">
<wsc:Setting.ActionContent>
<ToggleSwitch
Width="120"
IsEnabled="{Binding IsElevated}"
IsOn="{Binding Options.IsAdvancedLaunchOptionsEnabled, Mode=TwoWay}"
Style="{StaticResource ToggleSwitchSettingStyle}"/>
</wsc:Setting.ActionContent>
</wsc:Setting>
<InfoBar
IsClosable="False"
IsOpen="True"

View File

@@ -13,9 +13,9 @@
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shcp="using:Snap.Hutao.Control.Panel"
xmlns:shct="using:Snap.Hutao.Control.Text"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvc="using:Snap.Hutao.View.Control"
d:DataContext="{d:DesignInstance Type=shv:WikiAvatarViewModel}"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
d:DataContext="{d:DesignInstance Type=shvw:WikiAvatarViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Control;
using Snap.Hutao.ViewModel;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.View.Page;

View File

@@ -12,10 +12,10 @@
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shcp="using:Snap.Hutao.Control.Panel"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
xmlns:wsc="using:WinUICommunity.SettingsUI.Controls"
d:DataContext="{d:DesignInstance Type=shv:WikiMonsterViewModel}"
d:DataContext="{d:DesignInstance Type=shvw:WikiMonsterViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Control;
using Snap.Hutao.ViewModel;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.View.Page;

View File

@@ -13,9 +13,9 @@
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shcp="using:Snap.Hutao.Control.Panel"
xmlns:shct="using:Snap.Hutao.Control.Text"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:shvc="using:Snap.Hutao.View.Control"
d:DataContext="{d:DesignInstance Type=shv:WikiWeaponViewModel}"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
d:DataContext="{d:DesignInstance Type=shvw:WikiWeaponViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>

View File

@@ -2,7 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Control;
using Snap.Hutao.ViewModel;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.View.Page;

View File

@@ -1,7 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Binding;
namespace Snap.Hutao.ViewModel.Cultivation;
/// <summary>
/// 养成物品
@@ -15,7 +17,7 @@ internal sealed class CultivateEntryView : Item
/// <param name="entry">实体入口</param>
/// <param name="item">对应物品</param>
/// <param name="items">物品列表</param>
public CultivateEntryView(Entity.CultivateEntry entry, Item item, List<CultivateItem> items)
public CultivateEntryView(Model.Entity.CultivateEntry entry, Item item, List<CultivateItemView> items)
{
Id = entry.Id;
EntryId = entry.InnerId;
@@ -39,7 +41,7 @@ internal sealed class CultivateEntryView : Item
/// <summary>
/// 实体
/// </summary>
public List<CultivateItem> Items { get; set; } = default!;
public List<CultivateItemView> Items { get; set; } = default!;
/// <summary>
/// 是否为今日的材料

View File

@@ -2,22 +2,23 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model.Binding;
using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Cultivation;
namespace Snap.Hutao.ViewModel.Cultivation;
/// <summary>
/// 养成物品
/// </summary>
[HighQuality]
internal sealed class CultivateItem : ObservableObject, IEntityWithMetadata<Entity.CultivateItem, Material>
internal sealed class CultivateItemView : ObservableObject, IEntityWithMetadata<Model.Entity.CultivateItem, Material>
{
/// <summary>
/// 养成物品
/// </summary>
/// <param name="entity">实体</param>
/// <param name="inner">元数据</param>
public CultivateItem(Entity.CultivateItem entity, Material inner)
public CultivateItemView(Model.Entity.CultivateItem entity, Material inner)
{
Entity = entity;
Inner = inner;
@@ -31,7 +32,7 @@ internal sealed class CultivateItem : ObservableObject, IEntityWithMetadata<Enti
/// <summary>
/// 实体
/// </summary>
public Entity.CultivateItem Entity { get; }
public Model.Entity.CultivateItem Entity { get; }
/// <summary>
/// 是否完成此项

View File

@@ -3,7 +3,6 @@
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Model.Binding.Cultivation;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Service.Abstraction;
@@ -31,7 +30,7 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
private ObservableCollection<CultivateProject>? projects;
private CultivateProject? selectedProject;
private List<Model.Binding.Inventory.InventoryItem>? inventoryItems;
private List<InventoryItemView>? inventoryItems;
private ObservableCollection<CultivateEntryView>? cultivateEntries;
private ObservableCollection<StatisticsCultivateItem>? statisticsItems;
@@ -39,8 +38,6 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
/// 构造一个新的养成视图模型
/// </summary>
/// <param name="serviceProvider">服务提供器</param>
/// <param name="metadataService">元数据服务</param>
/// <param name="logger">日志器</param>
public CultivationViewModel(IServiceProvider serviceProvider)
{
cultivationService = serviceProvider.GetRequiredService<ICultivationService>();
@@ -51,9 +48,9 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
AddProjectCommand = new AsyncRelayCommand(AddProjectAsync);
RemoveProjectCommand = new AsyncRelayCommand<CultivateProject>(RemoveProjectAsync);
RemoveEntryCommand = new AsyncRelayCommand<CultivateEntryView>(RemoveEntryAsync);
SaveInventoryItemCommand = new RelayCommand<Model.Binding.Inventory.InventoryItem>(SaveInventoryItem);
SaveInventoryItemCommand = new RelayCommand<InventoryItemView>(SaveInventoryItem);
NavigateToPageCommand = new RelayCommand<string>(NavigateToPage);
FinishStateCommand = new RelayCommand<Model.Binding.Cultivation.CultivateItem>(UpdateFinishedState);
FinishStateCommand = new RelayCommand<CultivateItemView>(UpdateFinishedState);
}
/// <summary>
@@ -79,7 +76,7 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
/// <summary>
/// 物品列表
/// </summary>
public List<Model.Binding.Inventory.InventoryItem>? InventoryItems { get => inventoryItems; set => SetProperty(ref inventoryItems, value); }
public List<InventoryItemView>? InventoryItems { get => inventoryItems; set => SetProperty(ref inventoryItems, value); }
/// <summary>
/// 养成列表
@@ -203,7 +200,7 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
}
}
private void SaveInventoryItem(Model.Binding.Inventory.InventoryItem? inventoryItem)
private void SaveInventoryItem(InventoryItemView? inventoryItem)
{
if (inventoryItem != null)
{
@@ -212,7 +209,7 @@ internal sealed class CultivationViewModel : Abstraction.ViewModel
}
}
private void UpdateFinishedState(Model.Binding.Cultivation.CultivateItem? item)
private void UpdateFinishedState(CultivateItemView? item)
{
if (item != null)
{

View File

@@ -1,7 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Model.Binding.Cultivation;
namespace Snap.Hutao.ViewModel.Cultivation;
/// <summary>
/// 游戏内星期中的天

View File

@@ -2,15 +2,16 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model.Binding;
using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Inventory;
namespace Snap.Hutao.ViewModel.Cultivation;
/// <summary>
/// 背包物品
/// </summary>
[HighQuality]
internal sealed class InventoryItem : ObservableObject, IEntityWithMetadata<Entity.InventoryItem, Material>
internal sealed class InventoryItemView : ObservableObject, IEntityWithMetadata<Model.Entity.InventoryItem, Material>
{
/// <summary>
/// 创建一个新的背包物品
@@ -18,7 +19,7 @@ internal sealed class InventoryItem : ObservableObject, IEntityWithMetadata<Enti
/// <param name="entity">实体</param>
/// <param name="inner">元数据</param>
/// <param name="saveCommand">保存命令</param>
public InventoryItem(Entity.InventoryItem entity, Material inner, ICommand saveCommand)
public InventoryItemView(Model.Entity.InventoryItem entity, Material inner, ICommand saveCommand)
{
Entity = entity;
Inner = inner;
@@ -28,7 +29,7 @@ internal sealed class InventoryItem : ObservableObject, IEntityWithMetadata<Enti
/// <summary>
/// 实体
/// </summary>
public Entity.InventoryItem Entity { get; set; }
public Model.Entity.InventoryItem Entity { get; set; }
/// <summary>
/// 元数据

View File

@@ -3,7 +3,7 @@
using Snap.Hutao.Model.Metadata.Item;
namespace Snap.Hutao.Model.Binding.Cultivation;
namespace Snap.Hutao.ViewModel.Cultivation;
/// <summary>
/// 仅用于统计总数的养成物品
@@ -16,7 +16,7 @@ internal sealed class StatisticsCultivateItem
/// </summary>
/// <param name="inner">材料</param>
/// <param name="entity">实体</param>
public StatisticsCultivateItem(Material inner, Entity.CultivateItem entity)
public StatisticsCultivateItem(Material inner, Model.Entity.CultivateItem entity)
{
Inner = inner;
Count = entity.Count;

View File

@@ -53,6 +53,7 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
gameService = serviceProvider.GetRequiredService<IGameService>();
memoryCache = serviceProvider.GetRequiredService<IMemoryCache>();
Options = serviceProvider.GetRequiredService<LaunchOptions>();
AppOptions = serviceProvider.GetRequiredService<AppOptions>();
this.serviceProvider = serviceProvider;
LaunchCommand = new AsyncRelayCommand(LaunchAsync, AsyncRelayCommandOptions.AllowConcurrentExecutions);
@@ -100,6 +101,11 @@ internal sealed class LaunchGameViewModel : Abstraction.ViewModel
/// </summary>
public LaunchOptions Options { get; }
/// <summary>
/// 应用选项
/// </summary>
public AppOptions AppOptions { get; }
/// <summary>
/// 游戏资源
/// </summary>

View File

@@ -1,31 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Model.Binding;
using Snap.Hutao.Service.Game;
using System.IO;
using System.Text;
namespace Snap.Hutao.ViewModel.Game;
/// <summary>
/// 截图
/// </summary>
internal sealed class Screenshot : INameIcon
{
/// <summary>
/// 构造一个新的截图
/// </summary>
/// <param name="path">路径</param>
public Screenshot(string path)
{
Name = $"{new FileInfo(path).CreationTime}";
Icon = path.ToUri();
}
/// <inheritdoc/>
public string Name { get; }
/// <inheritdoc/>
public Uri Icon { get; }
}

View File

@@ -1,28 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Service.Game;
namespace Snap.Hutao.ViewModel.Game;
/// <summary>
/// 截图视图模型
/// </summary>
[Injection(InjectAs.Scoped)]
internal sealed class ScreenshotViewModel : Abstraction.ViewModel
{
/// <summary>
/// 构造一个新的截图视图模型
/// </summary>
/// <param name="gameService">游戏服务</param>
public ScreenshotViewModel(IGameService gameService)
{
}
/// <inheritdoc/>
protected override async Task OpenUIAsync()
{
}
}

View File

@@ -8,6 +8,7 @@ using Microsoft.Windows.AppLifecycle;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Core.IO.DataTransfer;
using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Core.Windowing;
using Snap.Hutao.Factory.Abstraction;
@@ -162,6 +163,11 @@ internal sealed class SettingViewModel : Abstraction.ViewModel
/// </summary>
public ExperimentalFeaturesViewModel Experimental { get; }
/// <summary>
/// 是否提权
/// </summary>
public bool IsElevated { get => Activation.GetElevated(); }
/// <summary>
/// 设置游戏路径命令
/// </summary>
@@ -272,15 +278,16 @@ internal sealed class SettingViewModel : Abstraction.ViewModel
private async Task SetDataFolderAsync()
{
IPickerFactory pickerFactory = serviceProvider.GetRequiredService<IPickerFactory>();
FolderPicker picker = pickerFactory.GetFolderPicker();
(bool isOk, string folder) = await picker.TryPickSingleFolderAsync().ConfigureAwait(false);
(bool isOk, string folder) = await serviceProvider
.GetRequiredService<IPickerFactory>()
.GetFolderPicker()
.TryPickSingleFolderAsync()
.ConfigureAwait(false);
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
if (isOk)
{
LocalSetting.Set(SettingKeys.DataFolderPath, folder);
infoBarService.Success(SH.ViewModelSettingSetDataFolderSuccess);
serviceProvider.GetRequiredService<IInfoBarService>().Success(SH.ViewModelSettingSetDataFolderSuccess);
}
}
@@ -292,8 +299,7 @@ internal sealed class SettingViewModel : Abstraction.ViewModel
private void CopyDeviceId()
{
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
Clipboard.SetText(DeviceId);
infoBarService.Success(SH.ViewModelSettingCopyDeviceIdSuccess);
serviceProvider.GetRequiredService<IInfoBarService>().Success(SH.ViewModelSettingCopyDeviceIdSuccess);
}
}

View File

@@ -2,10 +2,11 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata;
namespace Snap.Hutao.Model.Binding.BaseValue;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 基础数值信息
@@ -101,7 +102,7 @@ internal sealed class BaseValueInfo : ObservableObject
value += addValue;
}
values.Add(Metadata.Converter.PropertyDescriptor.FormatNameValue(propValue.Property, value));
values.Add(Model.Metadata.Converter.PropertyDescriptor.FormatNameValue(propValue.Property, value));
}
Values = values;

View File

@@ -5,7 +5,7 @@ using Snap.Hutao.Model.Metadata.Avatar;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Primitive;
namespace Snap.Hutao.Model.Binding.Hutao;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 料理奖励视图

View File

@@ -3,7 +3,7 @@
using Snap.Hutao.Model.Intrinsic;
namespace Snap.Hutao.Model.Binding.BaseValue;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 战斗属性与初始值

View File

@@ -5,8 +5,6 @@ using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.WinUI.UI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Model.Binding.BaseValue;
using Snap.Hutao.Model.Binding.Hutao;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Immutable;
@@ -30,7 +28,7 @@ using CalcConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumptio
using CalcItem = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Item;
using CalcItemHelper = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.ItemHelper;
namespace Snap.Hutao.ViewModel;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 角色资料视图模型

View File

@@ -3,7 +3,6 @@
using CommunityToolkit.WinUI.UI;
using Microsoft.Extensions.DependencyInjection;
using Snap.Hutao.Model.Binding.BaseValue;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Monster;
@@ -11,7 +10,7 @@ using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Metadata;
using System.Collections.Immutable;
namespace Snap.Hutao.ViewModel;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 怪物资料视图模型

View File

@@ -5,7 +5,6 @@ using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.WinUI.UI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Primitives;
using Snap.Hutao.Model.Binding.BaseValue;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Immutable;
@@ -26,7 +25,7 @@ using CalcAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.A
using CalcClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
using CalcConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Consumption;
namespace Snap.Hutao.ViewModel;
namespace Snap.Hutao.ViewModel.Wiki;
/// <summary>
/// 武器资料视图模型