Skip to content

Commit

Permalink
Merge pull request #2013 from DGP-Studio/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Lightczx authored Oct 3, 2024
2 parents 36f5c36 + b6db150 commit 76ccf70
Show file tree
Hide file tree
Showing 226 changed files with 4,095 additions and 2,167 deletions.
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ version: 1.0.{build}
branches:
only:
- "release"
build_cloud: HUTAO-ACTIONS
# build_cloud: HUTAO-ACTIONS
build_cloud: GCE
image: Visual Studio 2022
clone_depth: 3
clone_folder: C:\Users\Public\appveyor\Snap.Hutao
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ internal sealed partial class NotifyPropertyChangedBox<TNotifyPropertyChanged, T
{
private readonly TNotifyPropertyChanged notifyPropertyChanged;
private readonly string propertyName;
private readonly Func<TNotifyPropertyChanged, T> valueAccessor;
private readonly Func<TNotifyPropertyChanged, T> valueFactory;

public NotifyPropertyChangedBox(T value, TNotifyPropertyChanged notifyPropertyChanged, string propertyName, Func<TNotifyPropertyChanged, T> valueAccessor)
public NotifyPropertyChangedBox(T value, TNotifyPropertyChanged notifyPropertyChanged, string propertyName, Func<TNotifyPropertyChanged, T> valueFactory)
: base(value)
{
this.notifyPropertyChanged = notifyPropertyChanged;
this.propertyName = propertyName;
this.valueAccessor = valueAccessor;
this.valueFactory = valueFactory;
notifyPropertyChanged.PropertyChanged += OnPropertyChanged;
}

Expand All @@ -35,6 +35,6 @@ private void OnPropertyChanged(object? sender, PropertyChangedEventArgs args)
}

(Value as IDisposable)?.Dispose();
Value = valueAccessor(notifyPropertyChanged);
Value = valueFactory(notifyPropertyChanged);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@

namespace Snap.Hutao.Core.DependencyInjection;

/// <summary>
/// 依赖注入
/// </summary>
internal static class DependencyInjection
{
/// <summary>
/// 初始化依赖注入
/// </summary>
/// <returns>服务提供器</returns>
public static ServiceProvider Initialize()
{
ServiceProvider serviceProvider = new ServiceCollection()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ public static IServiceCollection AddConfiguredHttpClients(this IServiceCollectio
.ConfigurePrimaryHttpMessageHandler((handler, provider) =>
{
SocketsHttpHandler typedHandler = (SocketsHttpHandler)handler;
typedHandler.AllowAutoRedirect = true;
typedHandler.UseProxy = true;
typedHandler.MaxConnectionsPerServer = 16;
typedHandler.Proxy = provider.GetRequiredService<HttpProxyUsingSystemProxy>();
});
})
Expand All @@ -36,7 +34,6 @@ public static IServiceCollection AddConfiguredHttpClients(this IServiceCollectio
{
SocketsHttpHandler typedHandler = (SocketsHttpHandler)handler;
typedHandler.ConnectTimeout = TimeSpan.FromSeconds(30);
typedHandler.AllowAutoRedirect = true;
typedHandler.UseProxy = true;
typedHandler.MaxConnectionsPerServer = 16;
typedHandler.Proxy = provider.GetRequiredService<HttpProxyUsingSystemProxy>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Snap.Hutao.Core.ExceptionService;

internal sealed class ExceptionFormat
{
private static readonly string SectionSeparator = new('-', 40);
private static readonly string SectionSeparator = "----------------------------------------";

public static string Format(Exception exception)
{
Expand Down
8 changes: 3 additions & 5 deletions src/Snap.Hutao/Snap.Hutao/Core/IO/DirectoryOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,17 @@ public static unsafe bool UnsafeRename(string path, string name, FILEOPERATION_F

using (fileOperation)
{
IFileOperation* pFileOperation = (IFileOperation*)fileOperation.ThisPtr;

if (!SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out ObjectReference<IShellItem.Vftbl> shellItem)))
{
return false;
}

using (shellItem)
{
pFileOperation->SetOperationFlags(flags);
pFileOperation->RenameItem(shellItem, name, default!);
fileOperation.SetOperationFlags(flags);
fileOperation.RenameItem(shellItem, name, default!);

return SUCCEEDED(pFileOperation->PerformOperations());
return SUCCEEDED(fileOperation.PerformOperations());
}
}
}
Expand Down
20 changes: 4 additions & 16 deletions src/Snap.Hutao/Snap.Hutao/Core/IO/FileOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,15 @@ public static unsafe bool UnsafeDelete(string path)

using (fileOperation)
{
IFileOperation* pFileOperation = (IFileOperation*)fileOperation.ThisPtr;

if (!SUCCEEDED(SHCreateItemFromParsingName(path, default, in IShellItem.IID, out ObjectReference<IShellItem.Vftbl> shellItem)))
{
return false;
}

using (shellItem)
{
IShellItem* pShellItem = (IShellItem*)shellItem.ThisPtr;

pFileOperation->DeleteItem(pShellItem, default!);

return SUCCEEDED(pFileOperation->PerformOperations());
fileOperation.DeleteItem(shellItem, default!);
return SUCCEEDED(fileOperation.PerformOperations());
}
}
}
Expand All @@ -103,29 +98,22 @@ public static unsafe bool UnsafeMove(string sourceFileName, string destFileName)

using (fileOperation)
{
IFileOperation* pFileOperation = (IFileOperation*)fileOperation.ThisPtr;

if (!SUCCEEDED(SHCreateItemFromParsingName(sourceFileName, default, in IShellItem.IID, out ObjectReference<IShellItem.Vftbl> sourceShellItem)))
{
return false;
}

using (sourceShellItem)
{
IShellItem* pSourceShellItem = (IShellItem*)sourceShellItem.ThisPtr;

if (!SUCCEEDED(SHCreateItemFromParsingName(destFileName, default, in IShellItem.IID, out ObjectReference<IShellItem.Vftbl> destShellItem)))
{
return false;
}

using (destShellItem)
{
IShellItem* pDestShellItem = (IShellItem*)destShellItem.ThisPtr;

pFileOperation->MoveItem(pSourceShellItem, destShellItem, default, default!);

return SUCCEEDED(pFileOperation->PerformOperations());
fileOperation.MoveItem(sourceShellItem, destShellItem, default, default!);
return SUCCEEDED(fileOperation.PerformOperations());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private void Initialize(out string containerStringSID)
}
finally
{
// This function returns 1 rather than 0 specfied in the document.
// This function returns 1 rather than 0 specified in the document.
_ = NetworkIsolationFreeAppContainers(pContainers);
}

Expand All @@ -93,9 +93,12 @@ private void Initialize(out string containerStringSID)
}
finally
{
for (uint index = 0; index < count; index++)
if (pSids is not null)
{
HeapFree(GetProcessHeap(), 0, pSids[index].Sid);
for (uint index = 0; index < count; index++)
{
HeapFree(GetProcessHeap(), 0, pSids[index].Sid);
}
}

HeapFree(GetProcessHeap(), 0, pSids);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace Snap.Hutao.Core.IO.Http.Sharding;

internal sealed class HttpShardCopyWorkerOptions<TStatus>
{
private readonly LazySlim<SafeFileHandle> lazyDestinationFileHandle;

private bool isReadOnly;
private HttpClient httpClient = default!;
private string sourceUrl = default!;
Expand All @@ -19,7 +21,10 @@ internal sealed class HttpShardCopyWorkerOptions<TStatus>
private int bufferSize = 80 * 1024;
private int maxDegreeOfParallelism = Environment.ProcessorCount;

private SafeFileHandle? destinationFileHandle;
public HttpShardCopyWorkerOptions()
{
lazyDestinationFileHandle = new(GetFileHandle);
}

public HttpClient HttpClient
{
Expand Down Expand Up @@ -51,7 +56,7 @@ public string DestinationFilePath
}
}

public SafeFileHandle DestinationFileHandle { get => destinationFileHandle ??= GetFileHandle(); }
public SafeFileHandle DestinationFileHandle { get => lazyDestinationFileHandle.Value; }

public long ContentLength
{
Expand Down
2 changes: 1 addition & 1 deletion src/Snap.Hutao/Snap.Hutao/Core/IO/StreamCopyWorker.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using Snap.Hutao.Core.Threading.RateLimiting;
using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.RateLimiting;
using Snap.Hutao.Core.Threading.RateLimiting;

namespace Snap.Hutao.Core.IO;

Expand Down
63 changes: 63 additions & 0 deletions src/Snap.Hutao/Snap.Hutao/Core/Linq/DictionaryLookup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using System.Collections;

namespace Snap.Hutao.Core.Linq;

internal sealed partial class DictionaryLookup<TKey, TEnumerable, TValue> : ILookup<TKey, TValue>
where TKey : notnull
where TEnumerable : IEnumerable<TValue>
{
private readonly Dictionary<TKey, TEnumerable> inner;

public DictionaryLookup(Dictionary<TKey, TEnumerable> source)
{
inner = source;
}

public int Count { get => inner.Count; }

public IEnumerable<TValue> this[TKey key] { get => inner[key]; }

public bool Contains(TKey key)
{
return inner.ContainsKey(key);
}

public IEnumerator<IGrouping<TKey, TValue>> GetEnumerator()
{
foreach ((TKey key, TEnumerable values) in inner)
{
yield return new Grouping(key, values);
}
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

internal sealed class Grouping : IGrouping<TKey, TValue>
{
private readonly TEnumerable enumerable;

public Grouping(TKey key, TEnumerable enumerable)
{
Key = key;
this.enumerable = enumerable;
}

public TKey Key { get; }

public IEnumerator<TValue> GetEnumerator()
{
return enumerable.GetEnumerator();
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
13 changes: 13 additions & 0 deletions src/Snap.Hutao/Snap.Hutao/Core/Linq/DictionaryLookupExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.Linq;

internal static class DictionaryLookupExtension
{
public static ILookup<TKey, TValue> ToLookup<TKey, TValue>(this Dictionary<TKey, List<TValue>> dictionary)
where TKey : notnull
{
return new DictionaryLookup<TKey, List<TValue>, TValue>(dictionary);
}
}
1 change: 1 addition & 0 deletions src/Snap.Hutao/Snap.Hutao/Core/Setting/SettingKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ internal static class SettingKeys
public const string IsHomeCardGachaStatisticsPresented = "IsHomeCardGachaStatisticsPresented";
public const string IsHomeCardAchievementPresented = "IsHomeCardAchievementPresented";
public const string IsHomeCardDailyNotePresented = "IsHomeCardDailyNotePresented";
public const string IsHomeCardCalendarPresented = "IsHomeCardCalendarPresented";
#endregion

#region DevTool
Expand Down
14 changes: 5 additions & 9 deletions src/Snap.Hutao/Snap.Hutao/Core/Shell/ShellLinkInterop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,10 @@ private unsafe bool UnsafeTryCreateDesktopShoutcutForElevatedLaunch(string targe

using (shellLink)
{
IShellLinkW* pShellLink = (IShellLinkW*)shellLink.ThisPtr;

pShellLink->SetPath(elevatedLauncherPath);
pShellLink->SetArguments(runtimeOptions.FamilyName);
pShellLink->SetShowCmd(SHOW_WINDOW_CMD.SW_NORMAL);
pShellLink->SetIconLocation(targetLogoPath, 0);
shellLink.SetPath(elevatedLauncherPath);
shellLink.SetArguments(runtimeOptions.FamilyName);
shellLink.SetShowCmd(SHOW_WINDOW_CMD.SW_NORMAL);
shellLink.SetIconLocation(targetLogoPath, 0);

if (!SUCCEEDED(shellLink.TryAs(IPersistFile.IID, out ObjectReference<IPersistFile.Vftbl> persistFile)))
{
Expand All @@ -60,12 +58,10 @@ private unsafe bool UnsafeTryCreateDesktopShoutcutForElevatedLaunch(string targe

using (persistFile)
{
IPersistFile* pPersistFile = (IPersistFile*)persistFile.ThisPtr;

string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string target = Path.Combine(desktop, $"{SH.FormatAppNameAndVersion(runtimeOptions.Version)}.lnk");

return SUCCEEDED(pPersistFile->Save(target, false));
return SUCCEEDED(persistFile.Save(target, false));
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/Snap.Hutao/Snap.Hutao/Core/Threading/AsyncKeyedLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Snap.Hutao.Core.Threading;
internal sealed class AsyncKeyedLock<TKey>
where TKey : notnull
{
private static readonly Func<Task, object?, Releaser> Continuation = RunContinuation;

private readonly ConcurrentDictionary<TKey, AsyncSemaphore> semaphores;

public AsyncKeyedLock()
Expand All @@ -21,7 +23,6 @@ public AsyncKeyedLock(IEqualityComparer<TKey>? comparer)
semaphores = new(comparer);
}

[SuppressMessage("", "SH007")]
public Task<Releaser> LockAsync(TKey key)
{
Task wait;
Expand All @@ -31,7 +32,13 @@ public Task<Releaser> LockAsync(TKey key)
}

State stateObj = new(this, key);
return wait.IsCompleted ? Task.FromResult<Releaser>(new(stateObj)) : wait.ContinueWith((_, state) => new Releaser((State)state!), stateObj, default, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
return wait.IsCompleted ? Task.FromResult<Releaser>(new(stateObj)) : wait.ContinueWith(Continuation, stateObj, default, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}

private static Releaser RunContinuation(Task task, object? state)
{
ArgumentNullException.ThrowIfNull(state);
return new Releaser((State)state);
}

internal readonly struct Releaser : IDisposable
Expand Down
10 changes: 9 additions & 1 deletion src/Snap.Hutao/Snap.Hutao/Core/Threading/AsyncLock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace Snap.Hutao.Core.Threading;
[SuppressMessage("", "SH003")]
internal sealed class AsyncLock
{
private static readonly Func<Task, object?, Releaser> Continuation = RunContinuation;

private readonly AsyncSemaphore semaphore;
private readonly Task<Releaser> releaser;

Expand All @@ -20,7 +22,13 @@ public AsyncLock()
public Task<Releaser> LockAsync()
{
Task wait = semaphore.WaitAsync();
return wait.IsCompleted ? releaser : wait.ContinueWith((_, state) => new Releaser((AsyncLock)state!), this, default, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
return wait.IsCompleted ? releaser : wait.ContinueWith(Continuation, this, default, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
}

private static Releaser RunContinuation(Task task, object? state)
{
ArgumentNullException.ThrowIfNull(state);
return new Releaser((AsyncLock)state);
}

internal readonly struct Releaser : IDisposable
Expand Down
Loading

0 comments on commit 76ccf70

Please sign in to comment.