From 267f285101b2b40740eb243993e5f6f57bc27185 Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Tue, 10 Jan 2023 15:05:21 +0800 Subject: [PATCH] fix up oversea launcher support --- src/Snap.Hutao/.editorconfig | 21 +++--- .../TodoAnalyzer.cs | 52 -------------- .../Snap.Hutao/Model/Binding/User/User.cs | 3 +- .../Snap.Hutao/Service/AnnouncementService.cs | 37 ++++++---- .../GachaLogUrlWebCacheProvider.cs | 14 ++-- .../Snap.Hutao/Service/Game/GameService.cs | 4 +- .../Service/Game/Locator/ManualGameLocator.cs | 20 +++--- .../Game/Locator/UnityLogGameLocator.cs | 30 +++----- .../ViewModel/AnnouncementViewModel.cs | 2 +- .../Snap.Hutao/ViewModel/SettingViewModel.cs | 2 +- .../Snap.Hutao/Web/Enka/EnkaClient.cs | 6 +- .../Web/Hoyolab/App/Account/AccountClient.cs | 4 +- .../Web/Hoyolab/Bbs/User/UserClient.cs | 70 ------------------- .../Web/Hoyolab/Bbs/User/UserClient2.cs | 4 +- .../UseDynamicSecretAttribute.cs | 1 + .../Common/Announcement/AnnouncementClient.cs | 9 ++- .../Snap.Hutao/Web/HttpClientExtensions.cs | 12 ++-- .../Snap.Hutao/Web/Response/Response.cs | 32 +++++++-- ...MemoryExtensions.cs => MemoryExtension.cs} | 12 ++-- .../Snap.Hutao/Win32/StructMarshal.cs | 10 --- 20 files changed, 112 insertions(+), 233 deletions(-) delete mode 100644 src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs delete mode 100644 src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs rename src/Snap.Hutao/Snap.Hutao/Win32/{MemoryExtensions.cs => MemoryExtension.cs} (64%) diff --git a/src/Snap.Hutao/.editorconfig b/src/Snap.Hutao/.editorconfig index c3b2ed21..da1c9479 100644 --- a/src/Snap.Hutao/.editorconfig +++ b/src/Snap.Hutao/.editorconfig @@ -14,9 +14,9 @@ csharp_style_expression_bodied_accessors = when_on_single_line:silent csharp_style_expression_bodied_lambdas = when_on_single_line:silent csharp_style_expression_bodied_local_functions = false:silent csharp_style_conditional_delegate_call = true:suggestion -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent -csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:warning +csharp_style_var_when_type_is_apparent = false:warning +csharp_style_var_elsewhere = false:warning csharp_prefer_simple_using_statement = false:suggestion csharp_prefer_braces = true:silent csharp_style_namespace_declarations = file_scoped:silent @@ -24,11 +24,11 @@ csharp_prefer_static_local_function = false:suggestion [*.{cs,vb}] end_of_line = crlf -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion +dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion dotnet_code_quality_unused_parameters = non_public:suggestion dotnet_style_readonly_field = true:suggestion indent_size = 4 @@ -47,8 +47,8 @@ dotnet_style_prefer_auto_properties = false:silent dotnet_style_object_initializer = true:suggestion dotnet_style_collection_initializer = true:suggestion dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_return = true:suggestion dotnet_style_explicit_tuple_names = true:suggestion dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion @@ -165,6 +165,7 @@ dotnet_diagnostic.CA1805.severity = suggestion dotnet_diagnostic.VSTHRD111.severity = suggestion csharp_style_prefer_top_level_statements = true:silent csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion [*.vb] #### 命名样式 #### diff --git a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs deleted file mode 100644 index d432d856..00000000 --- a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/TodoAnalyzer.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Diagnostics; -using System.Collections.Immutable; - -namespace Snap.Hutao.SourceGeneration; - -/// -/// 高亮TODO -/// -[DiagnosticAnalyzer(LanguageNames.CSharp)] -internal class TodoAnalyzer : DiagnosticAnalyzer -{ - private static readonly DiagnosticDescriptor Descriptor = - new("SH0001", "TODO 项尚未实现", "此 TODO 项需要实现", "Standard", DiagnosticSeverity.Info, true); - - /// - public override ImmutableArray SupportedDiagnostics { get => ImmutableArray.Create(Descriptor); } - - /// - public override void Initialize(AnalysisContext context) - { - context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.EnableConcurrentExecution(); - - context.RegisterSyntaxTreeAction(HandleSyntaxTree); - } - - private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context) - { - SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken); - foreach (SyntaxTrivia node in root.DescendantTrivia(descendIntoTrivia: true)) - { - switch (node.Kind()) - { - case SyntaxKind.SingleLineCommentTrivia: - case SyntaxKind.MultiLineCommentTrivia: - string text = node.ToString().ToLowerInvariant(); - if (text.Contains("todo:")) - { - string hint = node.ToString().Substring(text.IndexOf("todo:") + 6); - DiagnosticDescriptor descriptor = new("SH0001", "TODO 项尚未实现", hint, "Standard", DiagnosticSeverity.Info, true); - context.ReportDiagnostic(Diagnostic.Create(descriptor, node.GetLocation())); - } - break; - } - } - } -} diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs index fca5edcc..9c558afe 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/User/User.cs @@ -153,10 +153,11 @@ public class User : ObservableObject using (IServiceScope scope = Ioc.Default.CreateScope()) { - UserInfo = await scope.ServiceProvider + Web.Response.Response response = await scope.ServiceProvider .GetRequiredService() .GetUserFullInfoAsync(Entity, token) .ConfigureAwait(false); + UserInfo = response.Data?.UserInfo; // 自动填充 Ltoken if (Ltoken == null) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AnnouncementService.cs b/src/Snap.Hutao/Snap.Hutao/Service/AnnouncementService.cs index 58487a0f..e739fa78 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AnnouncementService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AnnouncementService.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Caching.Memory; using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement; +using Snap.Hutao.Web.Response; using System.Text.RegularExpressions; namespace Snap.Hutao.Service; @@ -34,29 +35,39 @@ internal partial class AnnouncementService : IAnnouncementService // 缓存中存在记录,直接返回 if (memoryCache.TryGetValue(CacheKey, out object? cache)) { - return Must.NotNull((AnnouncementWrapper)cache!); + return (AnnouncementWrapper)cache!; } await ThreadHelper.SwitchToBackgroundAsync(); - AnnouncementWrapper? wrapper = await announcementClient + Response announcementWrapperResponse = await announcementClient .GetAnnouncementsAsync(cancellationToken) .ConfigureAwait(false); - List contents = await announcementClient - .GetAnnouncementContentsAsync(cancellationToken) - .ConfigureAwait(false); - Dictionary contentMap = contents - .ToDictionary(id => id.AnnId, content => content.Content); + if (announcementWrapperResponse.IsOk()) + { + AnnouncementWrapper wrapper = announcementWrapperResponse.Data; + Response> announcementContentResponse = await announcementClient + .GetAnnouncementContentsAsync(cancellationToken) + .ConfigureAwait(false); - Must.NotNull(wrapper!); + if (announcementContentResponse.IsOk()) + { + List contents = announcementContentResponse.Data.List; - // 将活动公告置于上方 - wrapper.List.Reverse(); + Dictionary contentMap = contents + .ToDictionary(id => id.AnnId, content => content.Content); - // 将公告内容联入公告列表 - JoinAnnouncements(contentMap, wrapper.List); + // 将活动公告置于上方 + wrapper.List.Reverse(); - return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30)); + // 将公告内容联入公告列表 + JoinAnnouncements(contentMap, wrapper.List); + + return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30)); + } + } + + return null!; } private static void JoinAnnouncements(Dictionary contentMap, List announcementListWrappers) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlWebCacheProvider.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlWebCacheProvider.cs index 4b0263f0..52aae5ef 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlWebCacheProvider.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/UrlProvider/GachaLogUrlWebCacheProvider.cs @@ -36,16 +36,10 @@ internal class GachaLogUrlWebCacheProvider : IGachaLogUrlProvider public static string GetCacheFile(string path) { string folder = Path.GetDirectoryName(path) ?? string.Empty; - var cacheDataPath = Path.Combine(folder, @"YuanShen_Data\webCaches\Cache\Cache_Data\data_2"); - var cacheDataPathIntl = Path.Combine(folder, @"GenshinImpact_Data\webCaches\Cache\Cache_Data\data_2"); - if (File.Exists(cacheDataPath)) - { - return cacheDataPath; - } - else - { - return cacheDataPathIntl; - } + string cacheDataPathChinese = Path.Combine(folder, @"YuanShen_Data\webCaches\Cache\Cache_Data\data_2"); + string cacheDataPathOversea = Path.Combine(folder, @"GenshinImpact_Data\webCaches\Cache\Cache_Data\data_2"); + + return File.Exists(cacheDataPathChinese) ? cacheDataPathChinese : cacheDataPathOversea; } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs index 4ca0e9b4..b040a071 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs @@ -200,6 +200,7 @@ internal class GameService : IGameService, IDisposable } /// + [SuppressMessage("", "IDE0046")] public bool IsGameRunning() { if (gameSemaphore.CurrentCount == 0) @@ -207,7 +208,8 @@ internal class GameService : IGameService, IDisposable return true; } - return Process.GetProcessesByName("YuanShen.exe").Any() || Process.GetProcessesByName("GenshinImpact.exe").Any(); + return Process.GetProcessesByName("YuanShen.exe").Any() + || Process.GetProcessesByName("GenshinImpact.exe").Any(); } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/ManualGameLocator.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/ManualGameLocator.cs index 90320f2b..6f4dae0a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/ManualGameLocator.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/ManualGameLocator.cs @@ -1,6 +1,7 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Snap.Hutao.Core.IO; using Snap.Hutao.Factory.Abstraction; using Windows.Storage; using Windows.Storage.Pickers; @@ -30,26 +31,21 @@ internal class ManualGameLocator : IGameLocator /// public Task> LocateGamePathAsync() { - List filenames = new List() - { - "YuanShen.exe", - "GenshinImpact.exe", - }; + List filenames = new(2) { "YuanShen.exe", "GenshinImpact.exe", }; return LocateInternalAsync(filenames); } private async Task> LocateInternalAsync(List fileNames) { FileOpenPicker picker = pickerFactory.GetFileOpenPicker(PickerLocationId.Desktop, "选择游戏本体", ".exe"); - if (await picker.PickSingleFileAsync() is StorageFile file) + (bool isPickerOk, FilePath file) = await picker.TryPickSingleFileAsync().ConfigureAwait(false); + + if (isPickerOk) { - string path = file.Path; - foreach (string fileName in fileNames) + string fileName = System.IO.Path.GetFileName(file); + if (fileNames.Contains(fileName)) { - if (path.Contains(fileName)) - { - return new(true, path); - } + return new(true, file); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/UnityLogGameLocator.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/UnityLogGameLocator.cs index b8a99764..164d754b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/UnityLogGameLocator.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/Locator/UnityLogGameLocator.cs @@ -21,10 +21,13 @@ internal partial class UnityLogGameLocator : IGameLocator { await ThreadHelper.SwitchToBackgroundAsync(); string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - string logFilePath = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\原神\output_log.txt"); - string logFilePathIntl = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\Genshin Impact\output_log.txt"); + string logFilePathChinese = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\原神\output_log.txt"); + string logFilePathOvsesea = Path.Combine(appDataPath, @"..\LocalLow\miHoYo\Genshin Impact\output_log.txt"); - using (TempFile? tempFile = TempFile.CreateFromFileCopy(logFilePath), tempFileIntl = TempFile.CreateFromFileCopy(logFilePathIntl)) + // We need to fallback the the cn server rather than os server. + string logFilePathFinal = File.Exists(logFilePathOvsesea) ? logFilePathOvsesea : logFilePathChinese; + + using (TempFile? tempFile = TempFile.CreateFromFileCopy(logFilePathFinal)) { if (tempFile != null) { @@ -40,30 +43,13 @@ internal partial class UnityLogGameLocator : IGameLocator string fullPath = Path.GetFullPath(Path.Combine(matchResult.Value, "..", entryName)); return new(true, fullPath); } - else if (tempFileIntl != null) - { - string content = File.ReadAllText(tempFileIntl.Path); - - Match matchResult = WarmupFileLineIntl().Match(content); - if (!matchResult.Success) - { - return new(false, $"在 Unity 日志文件中找不到游戏路径"); - } - - string entryName = matchResult.Groups[0].Value.Replace("_Data", ".exe"); - string fullPath = Path.GetFullPath(Path.Combine(matchResult.Value, "..", entryName)); - return new(true, fullPath); - } else { - return new(false, $"找不到 Unity 日志文件:\n{logFilePath}\n{logFilePathIntl}"); + return new(false, $"找不到 Unity 日志文件"); } } } - [GeneratedRegex(@"(?m).:/.+YuanShen_Data")] + [GeneratedRegex(@"(?m).:/.+(GenshinImpact_Data|YuanShen_Data)")] private static partial Regex WarmupFileLine(); - - [GeneratedRegex(@"(?m).:/.+GenshinImpact_Data")] - private static partial Regex WarmupFileLineIntl(); } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs index bd44028a..b90707ca 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs @@ -87,7 +87,7 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation else { IInfoBarService infoBarService = Ioc.Default.GetRequiredService(); - infoBarService.Warning("尚未安装 WebView2 运行时。"); + infoBarService.Warning("尚未安装 WebView2 Runtime"); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs index 442afe49..4192ec2d 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/SettingViewModel.cs @@ -61,7 +61,7 @@ internal class SettingViewModel : ObservableObject Experimental = experimental; - isEmptyHistoryWishVisibleEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.IsEmptyHistoryWishVisible, true.ToString()); + isEmptyHistoryWishVisibleEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.IsEmptyHistoryWishVisible, SettingEntryHelper.TrueString); IsEmptyHistoryWishVisible = bool.Parse(isEmptyHistoryWishVisibleEntry.Value!); selectedBackdropTypeEntry = appDbContext.Settings.SingleOrAdd(SettingEntry.SystemBackdropType, BackdropType.Mica.ToString()); diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs index 9b969926..380c0d21 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Enka/EnkaClient.cs @@ -40,7 +40,7 @@ internal class EnkaClient /// 玩家Uid /// 取消令牌 /// Enka API 响应 - public Task GetForwardDataAsync(PlayerUid playerUid, CancellationToken token) + public Task GetForwardDataAsync(PlayerUid playerUid, CancellationToken token = default) { return httpClient.TryCatchGetFromJsonAsync(string.Format(EnkaAPIHutaoForward, playerUid.Value), options, logger, token); } @@ -51,8 +51,8 @@ internal class EnkaClient /// 玩家Uid /// 取消令牌 /// Enka API 响应 - public Task GetDataAsync(PlayerUid playerUid, CancellationToken token) + public Task GetDataAsync(PlayerUid playerUid, CancellationToken token = default) { return httpClient.TryCatchGetFromJsonAsync(string.Format(EnkaAPI, playerUid.Value), options, logger, token); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/Account/AccountClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/Account/AccountClient.cs index c84f7105..947486d7 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/Account/AccountClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/App/Account/AccountClient.cs @@ -43,7 +43,7 @@ internal class AccountClient /// 取消令牌 /// 用户角色信息 [ApiInformation(Cookie = CookieType.Stoken, Salt = SaltType.K2)] - public async Task GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default) + public async Task> GenerateAuthenticationKeyAsync(User user, GenAuthKeyData data, CancellationToken token = default) { Response? resp = await httpClient .SetUser(user, CookieType.Stoken) @@ -53,6 +53,6 @@ internal class AccountClient .TryCatchPostAsJsonAsync>(ApiEndpoints.AppAuthGenAuthKey, data, options, logger, token) .ConfigureAwait(false); - return resp?.Data; + return Response.Response.DefaultIfNull(resp); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs deleted file mode 100644 index 51f728c2..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient; -using Snap.Hutao.Web.Hoyolab.Annotation; -using Snap.Hutao.Web.Response; -using System.Net.Http; - -namespace Snap.Hutao.Web.Hoyolab.Bbs.User; - -/// -/// 用户信息客户端 -/// -[HttpClient(HttpClientConfigration.XRpc)] -internal class UserClient -{ - private readonly HttpClient httpClient; - private readonly JsonSerializerOptions options; - private readonly ILogger logger; - - /// - /// 构造一个新的用户信息客户端 - /// - /// http客户端 - /// Json序列化选项 - /// 日志器 - public UserClient(HttpClient httpClient, JsonSerializerOptions options, ILogger logger) - { - this.httpClient = httpClient; - this.options = options; - this.logger = logger; - } - - /// - /// 获取当前用户详细信息 - /// - /// 用户 - /// 取消令牌 - /// 详细信息 - [ApiInformation(Cookie = CookieType.Ltoken)] - public async Task GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default) - { - Response? resp = await httpClient - .SetUser(user, CookieType.Ltoken) - .SetReferer(ApiEndpoints.BbsReferer) // Otherwise HTTP 403 - .TryCatchGetFromJsonAsync>(ApiEndpoints.UserFullInfo, options, logger, token) - .ConfigureAwait(false); - - return resp?.Data?.UserInfo; - } - - /// - /// 获取当前用户详细信息 - /// - /// 用户 - /// 取消令牌 - /// 详细信息 - [ApiInformation(Cookie = CookieType.Ltoken)] - public async Task GetUserFullInfoByUidAsync(Model.Entity.User user, CancellationToken token = default) - { - Response? resp = await httpClient - - // .SetUser(user, CookieType.Cookie) - .SetReferer(ApiEndpoints.BbsReferer) // Otherwise HTTP 403 - .TryCatchGetFromJsonAsync>(ApiEndpoints.UserFullInfoQuery(user.Aid!), options, logger, token) - .ConfigureAwait(false); - - return resp?.Data?.UserInfo; - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient2.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient2.cs index 560eb9df..f863be9e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient2.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Bbs/User/UserClient2.cs @@ -40,7 +40,7 @@ internal class UserClient2 /// 取消令牌 /// 详细信息 [ApiInformation(Cookie = CookieType.Stoken, Salt = SaltType.K2)] - public async Task GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default) + public async Task> GetUserFullInfoAsync(Model.Entity.User user, CancellationToken token = default) { Response? resp = await httpClient .SetUser(user, CookieType.Stoken) @@ -49,6 +49,6 @@ internal class UserClient2 .TryCatchGetFromJsonAsync>(ApiEndpoints.UserFullInfoQuery(user.Aid!), options, logger, token) .ConfigureAwait(false); - return resp?.Data?.UserInfo; + return Response.Response.DefaultIfNull(resp); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs index 9242f2d7..bb59fae8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/UseDynamicSecretAttribute.cs @@ -5,6 +5,7 @@ namespace Snap.Hutao.Web.Hoyolab.DynamicSecret; /// /// 指示此客户端使用动态密钥 +/// 会为依附类自动生成相关代码 /// [AttributeUsage(AttributeTargets.Class)] internal class UseDynamicSecretAttribute : Attribute diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs index b90616dc..8458f186 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/Hk4e/Common/Announcement/AnnouncementClient.cs @@ -36,13 +36,13 @@ internal class AnnouncementClient /// /// 取消令牌 /// 公告列表 - public async Task GetAnnouncementsAsync(CancellationToken cancellationToken = default) + public async Task> GetAnnouncementsAsync(CancellationToken cancellationToken = default) { Response? resp = await httpClient .TryCatchGetFromJsonAsync>(ApiEndpoints.AnnList, jsonSerializerOptions, logger, cancellationToken) .ConfigureAwait(false); - return resp?.Data; + return Response.Response.DefaultIfNull(resp); } /// @@ -50,13 +50,12 @@ internal class AnnouncementClient /// /// 取消令牌 /// 公告内容列表 - public async Task> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default) + public async Task>> GetAnnouncementContentsAsync(CancellationToken cancellationToken = default) { - // Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Response>? resp = await httpClient .TryCatchGetFromJsonAsync>>(ApiEndpoints.AnnContent, jsonSerializerOptions, logger, cancellationToken) .ConfigureAwait(false); - return EnumerableExtension.EmptyIfNull(resp?.Data?.List); + return Response.Response.DefaultIfNull(resp); } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs index 19abf86a..8c9e1031 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/HttpClientExtensions.cs @@ -28,7 +28,7 @@ internal static class HttpClientExtensions logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; } - catch (SocketException ex) + catch (IOException ex) { logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; @@ -38,7 +38,7 @@ internal static class HttpClientExtensions logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; } - catch (IOException ex) + catch (SocketException ex) { logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; @@ -59,7 +59,7 @@ internal static class HttpClientExtensions logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; } - catch (SocketException ex) + catch (IOException ex) { logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; @@ -69,7 +69,7 @@ internal static class HttpClientExtensions logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; } - catch (IOException ex) + catch (SocketException ex) { logger.LogWarning(EventIds.HttpException, ex, "请求异常已忽略"); return null; @@ -89,7 +89,7 @@ internal static class HttpClientExtensions { return null; } - catch (SocketException) + catch (IOException) { return null; } @@ -97,7 +97,7 @@ internal static class HttpClientExtensions { return null; } - catch (IOException) + catch (SocketException) { return null; } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs index b2d1d342..3c527260 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Response/Response.cs @@ -22,13 +22,9 @@ public class Response : ISupportValidation { ReturnCode = returnCode; Message = message; - - if (!Validate()) - { - Ioc.Default.GetRequiredService().Error(ToString()); - } - +#if DEBUG Ioc.Default.GetRequiredService>().LogInformation("Response [{resp}]", ToString()); +#endif } /// @@ -43,6 +39,18 @@ public class Response : ISupportValidation [JsonPropertyName("message")] public string Message { get; set; } = default!; + /// + /// 返回本体或带有消息提示的默认值 + /// + /// 类型 + /// 本体 + /// 本体或默认值,当本体为 null 时 返回默认值 + public static Response DefaultIfNull(Response? response) + { + // 0x26F19335 is a magic number that hashed from "Snap.Hutao" + return response ?? new(0x26F19335, "请求异常", default); + } + /// public bool Validate() { @@ -90,7 +98,17 @@ public class Response : Response, IJsResult [MemberNotNullWhen(true, nameof(Data))] public bool IsOk() { - return ReturnCode == 0; + if (ReturnCode == 0) + { +#pragma warning disable CS8775 + return true; +#pragma warning restore CS8775 + } + else + { + Ioc.Default.GetRequiredService().Error(ToString()); + return false; + } } /// diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtension.cs similarity index 64% rename from src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtensions.cs rename to src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtension.cs index 5090961f..9d0ab294 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/MemoryExtension.cs @@ -9,20 +9,22 @@ namespace Snap.Hutao.Win32; /// /// 内存拓展 for and /// -internal static class MemoryExtensions +internal static class MemoryExtension { /// /// 将 __CHAR_256 转换到 字符串 /// /// 目标字符数组 /// 结果字符串 - public static unsafe string AsString(this __CHAR_256 char256) + public static unsafe string AsString(this ref __CHAR_256 char256) { - byte* pszModule = (byte*)&char256; - return Encoding.UTF8.GetString(pszModule, StringLength(pszModule)); + fixed (CHAR* pszModule = &char256._0) + { + return Encoding.UTF8.GetString((byte*)pszModule, StringLength(pszModule)); + } } - private static unsafe int StringLength(byte* pszStr) + private static unsafe int StringLength(CHAR* pszStr) { int len = 0; while (*pszStr++ != 0) diff --git a/src/Snap.Hutao/Snap.Hutao/Win32/StructMarshal.cs b/src/Snap.Hutao/Snap.Hutao/Win32/StructMarshal.cs index 29df9fd4..eeb2f027 100644 --- a/src/Snap.Hutao/Snap.Hutao/Win32/StructMarshal.cs +++ b/src/Snap.Hutao/Snap.Hutao/Win32/StructMarshal.cs @@ -63,14 +63,4 @@ internal static class StructMarshal { return moduleEntry32.dwSize == 0; } - - /// - /// 判断结构实例是否为默认结构 - /// - /// 待测试的结构 - /// 是否为默认结构 - public static bool IsDefault(PlayerUid uid) - { - return uid.Value == default; - } } \ No newline at end of file