diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 296f57a7..c5896af8 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -8,12 +8,20 @@ body: - type: markdown attributes: value: | - 请按下方的要求填写完整的问题表单,以便我们更快的定位问题。 + 请按下方的要求填写完整的问题表单。 - type: textarea id: req attributes: - label: 你想要实现或优化的功能? - description: 详细的描述一下你想要的功能 + label: 背景与动机 + description: 添加此功能的理由 + validations: + required: true + + - type: textarea + id: req + attributes: + label: 想要实现或优化的功能 + description: 详细的描述一下你想要的功能,描述的越具体,采纳的可能性越高 validations: required: true \ No newline at end of file diff --git a/src/Snap.Hutao/SettingsUI/SettingsUI.csproj b/src/Snap.Hutao/SettingsUI/SettingsUI.csproj index 680dff53..be16117b 100644 --- a/src/Snap.Hutao/SettingsUI/SettingsUI.csproj +++ b/src/Snap.Hutao/SettingsUI/SettingsUI.csproj @@ -6,8 +6,9 @@ x64 win10-x64 true - latest + latest enable + true diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs index 6ab7d94f..7da1ff74 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs @@ -46,7 +46,7 @@ public partial class App : Application if (firstInstance.IsCurrent) { // manually invoke - Activation.Activate(firstInstance, activatedEventArgs); + Activation.NonRedirectToActivate(firstInstance, activatedEventArgs); firstInstance.Activated += Activation.Activate; ToastNotificationManagerCompat.OnActivated += Activation.NotificationActivate; diff --git a/src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs b/src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs index 0cab1bf0..607eafe9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/CommandLineBuilder.cs @@ -37,12 +37,6 @@ public class CommandLineBuilder return this; } - /// - public string Build() - { - return ToString(); - } - /// public override string ToString() { diff --git a/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs b/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs index 3e1d6e21..5cb2a538 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/CoreEnvironment.cs @@ -28,7 +28,7 @@ internal static class CoreEnvironment /// /// 米游社 Rpc 版本 /// - public const string HoyolabXrpcVersion = "2.41.0"; + public const string HoyolabXrpcVersion = "2.42.1"; /// /// 标准UA diff --git a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs index e3f1680e..a6519389 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/Activation.cs @@ -49,7 +49,21 @@ internal static class Activation _ = sender; if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated()) { - HandleActivationAsync(args).SafeForget(); + HandleActivationAsync(args, true).SafeForget(); + } + } + + /// + /// 触发激活事件 + /// + /// 发送方 + /// 激活参数 + public static void NonRedirectToActivate(object? sender, AppActivationArguments args) + { + _ = sender; + if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated()) + { + HandleActivationAsync(args, false).SafeForget(); } } @@ -76,24 +90,24 @@ internal static class Activation /// 异步响应激活事件 /// /// 任务 - private static async Task HandleActivationAsync(AppActivationArguments args) + private static async Task HandleActivationAsync(AppActivationArguments args, bool isRedirected) { if (ActivateSemaphore.CurrentCount > 0) { using (await ActivateSemaphore.EnterAsync().ConfigureAwait(false)) { - await HandleActivationCoreAsync(args).ConfigureAwait(false); + await HandleActivationCoreAsync(args, isRedirected).ConfigureAwait(false); } } } - private static async Task HandleActivationCoreAsync(AppActivationArguments args) + private static async Task HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected) { if (args.Kind == ExtendedActivationKind.Protocol) { if (args.TryGetProtocolActivatedUri(out Uri? uri)) { - await HandleUrlActivationAsync(uri).ConfigureAwait(false); + await HandleUrlActivationAsync(uri, isRedirected).ConfigureAwait(false); } } else if (args.Kind == ExtendedActivationKind.Launch) @@ -131,7 +145,7 @@ internal static class Activation .SafeForget(); } - private static async Task HandleUrlActivationAsync(Uri uri) + private static async Task HandleUrlActivationAsync(Uri uri, bool isRedirected) { UriBuilder builder = new(uri); @@ -144,21 +158,22 @@ internal static class Activation case "achievement": { await WaitMainWindowAsync().ConfigureAwait(false); - await HandleAchievementActionAsync(action, parameter).ConfigureAwait(false); + await HandleAchievementActionAsync(action, parameter, isRedirected).ConfigureAwait(false); break; } case "dailynote": { - await HandleDailyNoteActionAsync(action, parameter).ConfigureAwait(false); + await HandleDailyNoteActionAsync(action, parameter, isRedirected).ConfigureAwait(false); break; } } } - private static async Task HandleAchievementActionAsync(string action, string parameter) + private static async Task HandleAchievementActionAsync(string action, string parameter, bool isRedirected) { _ = parameter; + _ = isRedirected; switch (action) { case "/import": @@ -175,7 +190,7 @@ internal static class Activation } } - private static async Task HandleDailyNoteActionAsync(string action, string parameter) + private static async Task HandleDailyNoteActionAsync(string action, string parameter, bool isRedirected) { _ = parameter; switch (action) @@ -186,6 +201,14 @@ internal static class Activation .GetRequiredService() .RefreshDailyNotesAsync(true) .ConfigureAwait(false); + + // Check if it's redirected. + if (!isRedirected) + { + // It's a direct open process, should exit immediately. + Environment.Exit(0); + } + break; } } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/AppInstanceExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/AppInstanceExtension.cs index ea719c8e..007a0b4a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/AppInstanceExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/LifeCycle/AppInstanceExtension.cs @@ -19,14 +19,13 @@ internal static class AppInstanceExtension /// /// app实例 /// 参数 - [SuppressMessage("", "VSTHRD002")] [SuppressMessage("", "VSTHRD110")] - public static unsafe void RedirectActivationTo(this AppInstance appInstance, AppActivationArguments args) + public static void RedirectActivationTo(this AppInstance appInstance, AppActivationArguments args) { - HANDLE redirectEventHandle = CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, null); - Task.Run(() => + HANDLE redirectEventHandle = UnsafeCreateEvent(); + Task.Run(async () => { - appInstance.RedirectActivationToAsync(args).AsTask().Wait(); + await appInstance.RedirectActivationToAsync(args); SetEvent(redirectEventHandle); }); @@ -35,4 +34,9 @@ internal static class AppInstanceExtension // non-blocking CoWaitForMultipleObjects((uint)CWMO_FLAGS.CWMO_DEFAULT, INFINITE, handles, out uint _); } + + private static unsafe HANDLE UnsafeCreateEvent() + { + return CreateEvent((SECURITY_ATTRIBUTES*)null, true, false, null); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/TaskSchedulerHelper.cs b/src/Snap.Hutao/Snap.Hutao/Core/TaskSchedulerHelper.cs index 254468f5..e7526ac1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/TaskSchedulerHelper.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/TaskSchedulerHelper.cs @@ -45,4 +45,30 @@ internal static class TaskSchedulerHelper return false; } } + + /// + /// 卸载全部注册的任务 + /// + /// 是否卸载成功 + public static bool UnregisterAllTasks() + { + try + { + SchedulerTask? targetTask = TaskService.Instance.GetTask(DailyNoteRefreshTaskName); + if (targetTask != null) + { + TaskService.Instance.RootFolder.DeleteTask(DailyNoteRefreshTaskName); + } + + return true; + } + catch (UnauthorizedAccessException) + { + return false; + } + catch (COMException) + { + return false; + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/Team.cs b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/Team.cs index 37f94a52..3d94fe4f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/Team.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Binding/Hutao/Team.cs @@ -20,7 +20,7 @@ internal class Team : List public Team(ItemRate team, Dictionary idAvatarMap) : base(4) { - IEnumerable ids = team.Item.Split(',').Select(int.Parse); + IOrderedEnumerable ids = team.Item.Split(',').Select(int.Parse).OrderByDescending(x => x); foreach (int id in ids) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs index 32d14032..557afd31 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Game/GameService.cs @@ -246,7 +246,7 @@ internal class GameService : IGameService, IDisposable .Append("-screen-fullscreen", configuration.IsFullScreen ? 1 : 0) .Append("-screen-width", configuration.ScreenWidth) .Append("-screen-height", configuration.ScreenHeight) - .Build(); + .ToString(); Process game = new() { @@ -310,10 +310,6 @@ internal class GameService : IGameService, IDisposable { account = GameAccount.Create(name, registrySdk); - // sync cache - await ThreadHelper.SwitchToMainThreadAsync(); - gameAccounts.Add(GameAccount.Create(name, registrySdk)); - // sync database await ThreadHelper.SwitchToBackgroundAsync(); using (IServiceScope scope = scopeFactory.CreateScope()) @@ -324,6 +320,10 @@ internal class GameService : IGameService, IDisposable .AddAndSaveAsync(account) .ConfigureAwait(false); } + + // sync cache + await ThreadHelper.SwitchToMainThreadAsync(); + gameAccounts.Add(account); } } } diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj index 7f9de3c3..6bc32b0d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj +++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj @@ -5,7 +5,9 @@ 10.0.18362.0 Snap.Hutao app.manifest + x64 x64 + win10-x64 win10-x64 win10-$(Platform).pubxml true @@ -153,7 +155,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs index 47ffa12c..2e6768d3 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/DailyNoteVerificationDialog.xaml.cs @@ -50,9 +50,6 @@ public sealed partial class DailyNoteVerificationDialog : ContentDialog coreWebView2.SetCookie(user.CookieToken, user.Ltoken, null).SetMobileUserAgent(); dailyNoteJsInterface = new(coreWebView2, scope.ServiceProvider); -#if DEBUG - coreWebView2.OpenDevToolsWindow(); -#endif string query = $"?role_id={uid.Value}&server={uid.Region}"; coreWebView2.Navigate($"https://webstatic.mihoyo.com/app/community-game-records/index.html?bbs_presentation_style=fullscreen#/ys/daily/{query}"); } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs index d3c4aa5c..b0f5e8e2 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Dialog/SignInWebViewDialog.xaml.cs @@ -49,10 +49,6 @@ public sealed partial class SignInWebViewDialog : ContentDialog coreWebView2.SetCookie(user.CookieToken, user.Ltoken, null).SetMobileUserAgent(); signInJsInterface = new(coreWebView2, scope.ServiceProvider); - -#if DEBUG - coreWebView2.OpenDevToolsWindow(); -#endif coreWebView2.Navigate("https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?act_id=e202009291139501"); } @@ -61,4 +57,4 @@ public sealed partial class SignInWebViewDialog : ContentDialog signInJsInterface = null; scope.Dispose(); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml index 31ae0a57..aea974b4 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/DailyNotePage.xaml @@ -87,6 +87,10 @@ + diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs index f4f0e2f6..07ff3c9d 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/DailyNoteViewModel.cs @@ -11,6 +11,7 @@ using Snap.Hutao.Factory.Abstraction; using Snap.Hutao.Model; using Snap.Hutao.Model.Binding.User; using Snap.Hutao.Model.Entity; +using Snap.Hutao.Service.Abstraction; using Snap.Hutao.Service.DailyNote; using Snap.Hutao.Service.User; using Snap.Hutao.View.Dialog; @@ -67,6 +68,7 @@ internal class DailyNoteViewModel : ObservableObject, ISupportCancellation RefreshCommand = asyncRelayCommandFactory.Create(RefreshAsync); RemoveDailyNoteCommand = new RelayCommand(RemoveDailyNote); ModifyNotificationCommand = asyncRelayCommandFactory.Create(ModifyDailyNoteNotificationAsync); + DailyNoteVerificationCommand = asyncRelayCommandFactory.Create(VerifyDailyNoteVerificationAsync); } /// @@ -148,6 +150,11 @@ internal class DailyNoteViewModel : ObservableObject, ISupportCancellation /// public ICommand ModifyNotificationCommand { get; } + /// + /// 验证实时便笺命令 + /// + public ICommand DailyNoteVerificationCommand { get; } + private async Task OpenUIAsync() { UserAndRoles = await userService.GetRoleCollectionAsync().ConfigureAwait(true); @@ -194,4 +201,17 @@ internal class DailyNoteViewModel : ObservableObject, ISupportCancellation appDbContext.DailyNotes.UpdateAndSave(entry); } } + + private async Task VerifyDailyNoteVerificationAsync() + { + if (userService.Current != null && userService.Current.SelectedUserGameRole != null) + { + MainWindow mainWindow = Ioc.Default.GetRequiredService(); + await new DailyNoteVerificationDialog(mainWindow, userService.Current.Entity, userService.Current.SelectedUserGameRole).ShowAsync(); + } + else + { + Ioc.Default.GetRequiredService().Warning("请先选中账号与角色"); + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs index fbfdf00b..e3eccc7f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs +++ b/src/Snap.Hutao/Snap.Hutao/Web/Hoyolab/DynamicSecret/DynamicSecretHandler.cs @@ -21,8 +21,8 @@ public class DynamicSecretHandler : DelegatingHandler // https://github.com/UIGF-org/Hoyolab.Salt public static readonly ImmutableDictionary DynamicSecrets = new Dictionary() { - [nameof(SaltType.K2)] = "TsmyHpZg8gFAVKTtlPaL6YwMldzxZJxQ", - [nameof(SaltType.LK2)] = "osgT0DljLarYxgebPPHJFjdaxPfoiHGt", + [nameof(SaltType.K2)] = "jrU9ULHGZdM9Os3uGHOpjyRELYxby5cg", + [nameof(SaltType.LK2)] = "9gaxOdeeY2W9dw5x62pywhik8cxy5TIJ", [nameof(SaltType.X4)] = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs", [nameof(SaltType.X6)] = "t0qEgfub6cvueAPgR5m9aQWWVciEer7v", [nameof(SaltType.PROD)] = "JwYDpKvLj6MrMqqYU6jTKF17KNO2PXoS",