refine discord controller

This commit is contained in:
Lightczx
2024-04-28 16:46:07 +08:00
parent 074cc1194b
commit 45242ff8ce
5 changed files with 38 additions and 28 deletions

View File

@@ -1,6 +1,8 @@
// Copyright (c) DGP Studio. All rights reserved. // Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license. // Licensed under the MIT license.
using System.Diagnostics;
namespace Snap.Hutao.Core.Threading; namespace Snap.Hutao.Core.Threading;
internal delegate bool SpinWaitPredicate<T>(ref readonly T state); internal delegate bool SpinWaitPredicate<T>(ref readonly T state);
@@ -15,4 +17,23 @@ internal static class SpinWaitPolyfill
spinner.SpinOnce(); spinner.SpinOnce();
} }
} }
[SuppressMessage("", "SH002")]
public static unsafe bool SpinUntil<T>(ref T state, delegate*<ref readonly T, bool> condition, TimeSpan timeout)
{
long startTime = Stopwatch.GetTimestamp();
SpinWait spinner = default;
while (!condition(ref state))
{
spinner.SpinOnce();
if (timeout < Stopwatch.GetElapsedTime(startTime))
{
return false;
}
}
return true;
}
} }

View File

@@ -2,7 +2,7 @@
"profiles": { "profiles": {
"Snap.Hutao": { "Snap.Hutao": {
"commandName": "MsixPackage", "commandName": "MsixPackage",
"nativeDebugging": false, "nativeDebugging": true,
"doNotLaunchApp": false, "doNotLaunchApp": false,
"allowLocalNetworkLoopbackProperty": true "allowLocalNetworkLoopbackProperty": true
}, },

View File

@@ -7,32 +7,15 @@ using System.Collections.ObjectModel;
namespace Snap.Hutao.Service.DailyNote; namespace Snap.Hutao.Service.DailyNote;
/// <summary>
/// 实时便笺服务
/// </summary>
[HighQuality] [HighQuality]
internal interface IDailyNoteService internal interface IDailyNoteService
{ {
/// <summary>
/// 添加实时便笺
/// </summary>
/// <param name="userAndUid">角色</param>
/// <returns>任务</returns>
ValueTask AddDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default); ValueTask AddDailyNoteAsync(UserAndUid userAndUid, CancellationToken token = default);
ValueTask<ObservableCollection<DailyNoteEntry>> GetDailyNoteEntryCollectionAsync(bool forceRefresh = false, CancellationToken token = default); ValueTask<ObservableCollection<DailyNoteEntry>> GetDailyNoteEntryCollectionAsync(bool forceRefresh = false, CancellationToken token = default);
/// <summary>
/// 异步刷新实时便笺
/// </summary>
/// <returns>任务</returns>
ValueTask RefreshDailyNotesAsync(CancellationToken token = default); ValueTask RefreshDailyNotesAsync(CancellationToken token = default);
/// <summary>
/// 移除指定的实时便笺
/// </summary>
/// <param name="entry">指定的实时便笺</param>
/// <returns>任务</returns>
ValueTask RemoveDailyNoteAsync(DailyNoteEntry entry, CancellationToken token = default); ValueTask RemoveDailyNoteAsync(DailyNoteEntry entry, CancellationToken token = default);
ValueTask UpdateDailyNoteAsync(DailyNoteEntry entry, CancellationToken token = default); ValueTask UpdateDailyNoteAsync(DailyNoteEntry entry, CancellationToken token = default);

View File

@@ -21,7 +21,7 @@ internal static class DiscordController
private static long currentClientId; private static long currentClientId;
private static unsafe IDiscordCore* discordCorePtr; private static unsafe IDiscordCore* discordCorePtr;
private static bool isInitialized; private static bool isCallbackInitialized;
public static async ValueTask<DiscordResult> SetDefaultActivityAsync(DateTimeOffset startTime) public static async ValueTask<DiscordResult> SetDefaultActivityAsync(DateTimeOffset startTime)
{ {
@@ -108,7 +108,7 @@ internal static class DiscordController
public static unsafe void Stop() public static unsafe void Stop()
{ {
if (!isInitialized) if (!isCallbackInitialized)
{ {
return; return;
} }
@@ -147,13 +147,13 @@ internal static class DiscordController
discordCorePtr->set_log_hook(discordCorePtr, DiscordLogLevel.Debug, default, &DebugWriteDiscordMessage); discordCorePtr->set_log_hook(discordCorePtr, DiscordLogLevel.Debug, default, &DebugWriteDiscordMessage);
} }
if (isInitialized) if (isCallbackInitialized)
{ {
return; return;
} }
DiscordRunCallbacksAsync(StopTokenSource.Token).SafeForget(); DiscordRunCallbacksAsync(StopTokenSource.Token).SafeForget();
isInitialized = true; isCallbackInitialized = true;
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])]
static unsafe void DebugWriteDiscordMessage(void* state, DiscordLogLevel logLevel, sbyte* ptr) static unsafe void DebugWriteDiscordMessage(void* state, DiscordLogLevel logLevel, sbyte* ptr)
@@ -183,7 +183,7 @@ internal static class DiscordController
{ {
try try
{ {
DiscordResult result = DiscordCoreRunRunCallbacks(); DiscordResult result = RunDiscordCoreRunCallbacks();
if (result is not DiscordResult.Ok) if (result is not DiscordResult.Ok)
{ {
if (result is DiscordResult.NotRunning) if (result is DiscordResult.NotRunning)
@@ -200,11 +200,11 @@ internal static class DiscordController
} }
} }
} }
catch (SEHException ex) catch (Exception ex)
{ {
// Known error codes: // Known error codes:
// 0x80004005 E_FAIL // 0x80004005 E_FAIL
System.Diagnostics.Debug.WriteLine($"[Discord.GameSDK ERROR]:0x{ex.ErrorCode:X}"); System.Diagnostics.Debug.WriteLine($"[Discord.GameSDK ERROR]:0x{ex.HResult:X}");
} }
} }
} }
@@ -214,7 +214,7 @@ internal static class DiscordController
} }
} }
unsafe DiscordResult DiscordCoreRunRunCallbacks() unsafe DiscordResult RunDiscordCoreRunCallbacks()
{ {
if (discordCorePtr is not null) if (discordCorePtr is not null)
{ {
@@ -253,6 +253,7 @@ internal static class DiscordController
public DiscordUpdateActivityAsyncAction(IDiscordActivityManager* activityManagerPtr) public DiscordUpdateActivityAsyncAction(IDiscordActivityManager* activityManagerPtr)
{ {
this.activityManagerPtr = activityManagerPtr; this.activityManagerPtr = activityManagerPtr;
discordAsyncAction.Result = (DiscordResult)(-1);
} }
public DiscordResult WaitUpdateActivity(DiscordActivity activity) public DiscordResult WaitUpdateActivity(DiscordActivity activity)
@@ -262,7 +263,7 @@ internal static class DiscordController
activityManagerPtr->update_activity(activityManagerPtr, &activity, actionPtr, &HandleResult); activityManagerPtr->update_activity(activityManagerPtr, &activity, actionPtr, &HandleResult);
} }
SpinWaitPolyfill.SpinUntil(ref discordAsyncAction, &CheckActionCompleted); SpinWaitPolyfill.SpinUntil(ref discordAsyncAction, &CheckActionCompleted, TimeSpan.FromSeconds(5));
return discordAsyncAction.Result; return discordAsyncAction.Result;
} }

View File

@@ -50,10 +50,15 @@ internal sealed partial class DiscordService : IDiscordService, IDisposable
return false; return false;
} }
foreach (Process process in discordProcesses) foreach (ref readonly Process process in discordProcesses.AsSpan())
{ {
try try
{ {
if (string.Equals(process.MainWindowTitle, "Discord Updater", StringComparison.OrdinalIgnoreCase))
{
return false;
}
_ = process.Handle; _ = process.Handle;
} }
catch (Exception) catch (Exception)