fix several issues

This commit is contained in:
DismissedLight
2023-10-01 11:08:24 +08:00
parent 500888c2d1
commit bfe9837b36
18 changed files with 121 additions and 31 deletions

View File

@@ -5,5 +5,5 @@ namespace Snap.Hutao.Core.Shell;
internal interface IShellLinkInterop
{
void CreateDesktopShoutcutForElevatedLaunch();
bool TryCreateDesktopShoutcutForElevatedLaunch();
}

View File

@@ -15,11 +15,20 @@ internal sealed partial class ShellLinkInterop : IShellLinkInterop
{
private readonly RuntimeOptions runtimeOptions;
public void CreateDesktopShoutcutForElevatedLaunch()
public bool TryCreateDesktopShoutcutForElevatedLaunch()
{
string sourceLogoPath = Path.Combine(runtimeOptions.InstalledLocation, "Assets/Logo.ico");
string targetLogoPath = Path.Combine(runtimeOptions.DataFolder, "ShellLinkLogo.ico");
File.Copy(sourceLogoPath, targetLogoPath, true);
try
{
// System.IO.IOException: 无法加密指定的文件。
File.Copy(sourceLogoPath, targetLogoPath, true);
}
catch
{
return false;
}
IShellLinkW shellLink = (IShellLinkW)new ShellLink();
shellLink.SetPath("powershell");
@@ -34,5 +43,7 @@ internal sealed partial class ShellLinkInterop : IShellLinkInterop
IPersistFile persistFile = (IPersistFile)shellLink;
persistFile.Save(target, false);
return true;
}
}

View File

@@ -18,6 +18,7 @@ internal sealed class UIGF
/// <summary>
/// 信息
/// </summary>
[JsonRequired]
[JsonPropertyName("info")]
public UIGFInfo Info { get; set; } = default!;

View File

@@ -3741,6 +3741,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 创建桌面快捷方式失败 的本地化字符串。
/// </summary>
internal static string ViewModelSettingCreateDesktopShortcutFailed {
get {
return ResourceManager.GetString("ViewModelSettingCreateDesktopShortcutFailed", resourceCulture);
}
}
/// <summary>
/// 查找类似 设置数据目录成功,重启以应用更改 的本地化字符串。
/// </summary>
@@ -5325,6 +5334,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 版本更新前需要提前转换至与启动器匹配的服务器 的本地化字符串。
/// </summary>
internal static string ViewPageLaunchGameSwitchSchemeWarning {
get {
return ResourceManager.GetString("ViewPageLaunchGameSwitchSchemeWarning", resourceCulture);
}
}
/// <summary>
/// 查找类似 请在游戏内关闭垂直同步选项,需要高性能的显卡以支持更高的帧率 的本地化字符串。
/// </summary>

View File

@@ -1400,6 +1400,9 @@
<data name="ViewModelSettingCopyDeviceIdSuccess" xml:space="preserve">
<value>复制成功</value>
</data>
<data name="ViewModelSettingCreateDesktopShortcutFailed" xml:space="preserve">
<value>创建桌面快捷方式失败</value>
</data>
<data name="ViewModelSettingSetDataFolderSuccess" xml:space="preserve">
<value>设置数据目录成功,重启以应用更改</value>
</data>
@@ -1928,6 +1931,9 @@
<data name="ViewPageLaunchGameSwitchSchemeHeader" xml:space="preserve">
<value>服务器</value>
</data>
<data name="ViewPageLaunchGameSwitchSchemeWarning" xml:space="preserve">
<value>版本更新前需要提前转换至与启动器匹配的服务器</value>
</data>
<data name="ViewPageLaunchGameUnlockFpsDescription" xml:space="preserve">
<value>请在游戏内关闭垂直同步选项,需要高性能的显卡以支持更高的帧率</value>
</data>

View File

@@ -99,9 +99,17 @@ internal sealed partial class GachaLogHutaoCloudService : IGachaLogHutaoCloudSer
HutaoStatisticsFactoryMetadataContext context = new(idAvatarMap, idWeaponMap, gachaEvents);
GachaEventStatistics raw = response.Data;
HutaoStatisticsFactory factory = new(context);
HutaoStatistics statistics = factory.Create(raw);
return new(true, statistics);
try
{
HutaoStatisticsFactory factory = new(context);
HutaoStatistics statistics = factory.Create(raw);
return new(true, statistics);
}
catch
{
// 元数据未能即时更新导致异常?
return new(false, default!);
}
}
}

View File

@@ -147,4 +147,4 @@ internal sealed partial class LaunchScheme
ServerGlobalChannelOfficialSubChannelGoogle,
};
}
}
}

View File

@@ -194,6 +194,7 @@ internal sealed partial class UserService : IUserService, IUserServiceUnsafe
private static bool TryGetUser(ObservableCollection<BindingUser> users, string mid, [NotNullWhen(true)] out BindingUser? user)
{
// TODO: System.InvalidOperationException: Sequence contains more than one matching element
user = users.SingleOrDefault(u => u.Entity.Mid == mid);
return user is not null;
}

View File

@@ -260,7 +260,7 @@
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="17.6.11" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.18-beta">
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.46-beta">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -67,10 +67,18 @@
Severity="Informational"/>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameCommonHeader}"/>
<cwc:SettingsCard
Description="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"
Header="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8AB;}"
IsEnabled="{Binding HutaoOptions.IsElevated}">
<cwc:SettingsCard.Description>
<StackPanel>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeDescription}"/>
<TextBlock
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
Style="{StaticResource CaptionTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageLaunchGameSwitchSchemeWarning}"/>
</StackPanel>
</cwc:SettingsCard.Description>
<StackPanel Orientation="Horizontal">
<shvc:Elevation Margin="0,0,36,0" Visibility="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
<shccs:ComboBox2

View File

@@ -40,12 +40,7 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
.TryCatchGetFromJsonAsync<WebApiResponse<AccountInfoWrapper>>(ApiOsEndpoints.WebApiOsAccountLoginByCookie, options, logger, token)
.ConfigureAwait(false);
if (resp is not null)
{
return $"{resp.Data?.AccountInfo?.AccountId}";
}
return string.Empty;
return $"{resp?.Data?.AccountInfo?.AccountId}";
}
private async void OnRootLoaded(object sender, RoutedEventArgs e)
@@ -81,6 +76,11 @@ internal sealed partial class LoginHoyoverseUserPage : Microsoft.UI.Xaml.Control
IInfoBarService infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();
Cookie loginTicketCookie = Cookie.FromCoreWebView2Cookies(cookies);
if (loginTicketCookie.IsEmpty())
{
return;
}
string uid = await GetUidFromCookieAsync(Ioc.Default, loginTicketCookie).ConfigureAwait(false);
loginTicketCookie[Cookie.LOGIN_UID] = uid;

View File

@@ -255,6 +255,12 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
{
baseline.AvatarId = avatar.Id;
baseline.AvatarLevelCurrent = Math.Min(avatar.LevelNumber, baseline.AvatarLevelTarget);
if (avatar.Skills.Count < 3)
{
continue;
}
baseline.SkillList[0].Id = avatar.Skills[0].GroupId;
baseline.SkillList[0].LevelCurrent = Math.Min(avatar.Skills[0].LevelNumber, baseline.SkillList[0].LevelTarget);
baseline.SkillList[1].Id = avatar.Skills[1].GroupId;

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using Snap.Hutao.Service.GachaLog;
using Snap.Hutao.Service.Notification;
namespace Snap.Hutao.ViewModel.GachaLog;
@@ -12,6 +13,7 @@ namespace Snap.Hutao.ViewModel.GachaLog;
[ConstructorGenerated(CallBaseConstructor = true)]
internal sealed partial class GachaLogViewModelSlim : Abstraction.ViewModelSlim<View.Page.GachaLogPage>
{
private readonly IInfoBarService infoBarService;
private readonly ITaskContext taskContext;
private List<GachaStatisticsSlim>? statisticsList;
@@ -30,11 +32,18 @@ internal sealed partial class GachaLogViewModelSlim : Abstraction.ViewModelSlim<
if (await gachaLogService.InitializeAsync().ConfigureAwait(false))
{
List<GachaStatisticsSlim> list = await gachaLogService.GetStatisticsSlimListAsync().ConfigureAwait(false);
try
{
List<GachaStatisticsSlim> list = await gachaLogService.GetStatisticsSlimListAsync().ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
StatisticsList = list;
IsInitialized = true;
await taskContext.SwitchToMainThreadAsync();
StatisticsList = list;
IsInitialized = true;
}
catch (Exception ex)
{
infoBarService.Error(ex);
}
}
}
}

View File

@@ -270,7 +270,14 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
[Command("CreateDesktopShortcutCommand")]
private void CreateDesktopShortcutForElevatedLaunch()
{
shellLinkInterop.CreateDesktopShoutcutForElevatedLaunch();
infoBarService.Information(SH.ViewModelSettingActionComplete);
bool created = shellLinkInterop.TryCreateDesktopShoutcutForElevatedLaunch();
if (created)
{
infoBarService.Information(SH.ViewModelSettingActionComplete);
}
else
{
infoBarService.Warning(SH.ViewModelSettingCreateDesktopShortcutFailed);
}
}
}

View File

@@ -37,6 +37,11 @@ internal sealed partial class Cookie
set => inner[key] = value;
}
public bool IsEmpty()
{
return inner.Count <= 0;
}
/// <summary>
/// 解析Cookie字符串
/// </summary>

View File

@@ -54,16 +54,20 @@ internal sealed partial class AuthClient
/// <returns>包含token的字典</returns>
public async ValueTask<Response<ListWrapper<NameToken>>> GetMultiTokenByLoginTicketAsync(Cookie cookie, bool isOversea, CancellationToken token = default)
{
string loginTicket = cookie[Cookie.LOGIN_TICKET];
string loginUid = cookie[Cookie.LOGIN_UID];
Response<ListWrapper<NameToken>>? resp = null;
if (cookie.TryGetLoginTicket(out Cookie? loginTicketCookie))
{
string loginTicket = loginTicketCookie[Cookie.LOGIN_TICKET];
string loginUid = loginTicketCookie[Cookie.LOGIN_UID];
string url = isOversea
? ApiOsEndpoints.AuthMultiToken(loginTicket, loginUid)
: ApiEndpoints.AuthMultiToken(loginTicket, loginUid);
string url = isOversea
? ApiOsEndpoints.AuthMultiToken(loginTicket, loginUid)
: ApiEndpoints.AuthMultiToken(loginTicket, loginUid);
Response<ListWrapper<NameToken>>? resp = await httpClient
.TryCatchGetFromJsonAsync<Response<ListWrapper<NameToken>>>(url, options, logger, token)
.ConfigureAwait(false);
resp = await httpClient
.TryCatchGetFromJsonAsync<Response<ListWrapper<NameToken>>>(url, options, logger, token)
.ConfigureAwait(false);
}
return Response.Response.DefaultIfNull(resp);
}

View File

@@ -5,6 +5,8 @@ namespace Snap.Hutao.Web.Hutao.Geetest;
internal sealed class GeetestResponse
{
public static GeetestResponse InternalFailure { get; } = new() { Code = Response.Response.InternalFailure };
[JsonPropertyName("code")]
public int Code { get; set; }

View File

@@ -22,14 +22,18 @@ internal sealed partial class HomaGeetestClient
if (string.IsNullOrEmpty(template))
{
return new() { Code = Response.Response.InternalFailure };
return GeetestResponse.InternalFailure;
}
GeetestResponse? resp = await httpClient
.TryCatchGetFromJsonAsync<GeetestResponse>(template.Format(gt, challenge), options, logger, token)
.ConfigureAwait(false);
ArgumentNullException.ThrowIfNull(resp);
if (resp is null)
{
return GeetestResponse.InternalFailure;
}
return resp;
}
}