diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs b/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs index debe0818..84a95a90 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Caching/ImageCache.cs @@ -42,10 +42,20 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera private string? baseFolder; private string? cacheFolder; + private string CacheFolder + { + get => LazyInitializer.EnsureInitialized(ref cacheFolder, () => + { + baseFolder ??= serviceProvider.GetRequiredService().LocalCache; + DirectoryInfo info = Directory.CreateDirectory(Path.Combine(baseFolder, CacheFolderName)); + return info.FullName; + }); + } + /// public void RemoveInvalid() { - RemoveInternal(Directory.GetFiles(GetCacheFolder()).Where(file => IsFileInvalid(file, false))); + RemoveCore(Directory.GetFiles(CacheFolder).Where(file => IsFileInvalid(file, false))); } /// @@ -62,7 +72,7 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera return; } - string folder = GetCacheFolder(); + string folder = CacheFolder; string[] files = Directory.GetFiles(folder); List filesToDelete = []; @@ -75,16 +85,16 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera } } - RemoveInternal(filesToDelete); + RemoveCore(filesToDelete); } /// public async ValueTask GetFileFromCacheAsync(Uri uri) { string fileName = GetCacheFileName(uri); - string filePath = Path.Combine(GetCacheFolder(), fileName); + string filePath = Path.Combine(CacheFolder, fileName); - if (File.Exists(filePath) && new FileInfo(filePath).Length != 0) + if (!IsFileInvalid(filePath)) { return filePath; } @@ -94,10 +104,12 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera { if (concurrentTasks.TryAdd(fileName, taskCompletionSource.Task)) { + logger.LogDebug("Begin downloading image file from '{Uri}' to '{File}'", uri, filePath); await DownloadFileAsync(uri, filePath).ConfigureAwait(false); } else if (concurrentTasks.TryGetValue(fileName, out Task? task)) { + logger.LogDebug("Waiting for a queued image download task to complete for '{Uri}'", uri); await task.ConfigureAwait(false); } @@ -115,7 +127,7 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera public ValueFile GetFileFromCategoryAndName(string category, string fileName) { Uri dummyUri = Web.HutaoEndpoints.StaticRaw(category, fileName).ToUri(); - return Path.Combine(GetCacheFolder(), GetCacheFileName(dummyUri)); + return Path.Combine(CacheFolder, GetCacheFileName(dummyUri)); } private static string GetCacheFileName(Uri uri) @@ -137,17 +149,18 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera return fileInfo.Length == 0; } - private void RemoveInternal(IEnumerable filePaths) + private void RemoveCore(IEnumerable filePaths) { foreach (string filePath in filePaths) { try { File.Delete(filePath); + logger.LogInformation("Remove cached image succeed:{File}", filePath); } catch (Exception ex) { - logger.LogWarning(ex, "Remove Cache Image Failed:{File}", filePath); + logger.LogWarning(ex, "Remove cached image failed:{File}", filePath); } } } @@ -155,14 +168,17 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera [SuppressMessage("", "SH003")] private async Task DownloadFileAsync(Uri uri, string baseFile) { - logger.LogInformation("Begin downloading for {Uri}", uri); - int retryCount = 0; HttpClient httpClient = httpClientFactory.CreateClient(nameof(ImageCache)); while (retryCount < 3) { using (HttpResponseMessage message = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)) { + if (message.RequestMessage is { RequestUri: { } target } && target != uri) + { + logger.LogDebug("The Request '{Source}' has been redirected to '{Target}'", uri, target); + } + if (message.IsSuccessStatusCode) { using (Stream httpStream = await message.Content.ReadAsStreamAsync().ConfigureAwait(false)) @@ -181,7 +197,7 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera { retryCount++; TimeSpan delay = message.Headers.RetryAfter?.Delta ?? retryCountToDelay[retryCount]; - logger.LogInformation("Retry {Uri} after {Delay}.", uri, delay); + logger.LogInformation("Retry download '{Uri}' after {Delay}.", uri, delay); await Task.Delay(delay).ConfigureAwait(false); break; } @@ -192,18 +208,4 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera } } } - - private string GetCacheFolder() - { - if (cacheFolder is not null) - { - return cacheFolder; - } - - baseFolder ??= serviceProvider.GetRequiredService().LocalCache; - DirectoryInfo info = Directory.CreateDirectory(Path.Combine(baseFolder, CacheFolderName)); - cacheFolder = info.FullName; - - return cacheFolder; - } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Database/QueryableExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/Database/QueryableExtension.cs index b04feb64..4243b2f9 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Database/QueryableExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Database/QueryableExtension.cs @@ -14,7 +14,7 @@ namespace Snap.Hutao.Core.Database; internal static class QueryableExtension { /// - /// source.Where(predicate).ExecuteDelete() + /// source.Where(predicate).ExecuteDelete() /// /// 源类型 /// 源 @@ -27,7 +27,7 @@ internal static class QueryableExtension } /// - /// source.Where(predicate).ExecuteDeleteAsync(token) + /// source.Where(predicate).ExecuteDeleteAsync(token) /// /// 源类型 /// 源 diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/ICastService.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/ICastService.cs index 1ac33e46..cd21e0eb 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/ICastService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/ICastService.cs @@ -6,6 +6,7 @@ namespace Snap.Hutao.Core.DependencyInjection.Abstraction; /// /// 可转换类型服务 /// +[Obsolete("Not useful anymore")] internal interface ICastService { } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/INamedService.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/INamedService.cs deleted file mode 100644 index 1fc7b03d..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/INamedService.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Core.DependencyInjection.Abstraction; - -/// -/// 有名称的对象 -/// 指示该对象可通过名称区分 -/// -[Obsolete("无意义的接口")] -[HighQuality] -internal interface INamedService -{ - /// - /// 名称 - /// - string Name { get; } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/IOverseaSupport.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/IOverseaSupport.cs deleted file mode 100644 index 35145531..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/Abstraction/IOverseaSupport.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Core.DependencyInjection.Abstraction; - -/// -/// 海外服/HoYoLAB 可区分 -/// -[Obsolete("Use IOverseaSupportFactory instead")] -internal interface IOverseaSupport -{ - /// - /// 是否为 海外服/HoYoLAB - /// - public bool IsOversea { get; } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/CastServiceExtension.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/CastServiceExtension.cs index 16e65b75..d869b27d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/CastServiceExtension.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/CastServiceExtension.cs @@ -17,6 +17,7 @@ internal static class CastServiceExtension /// 目标转换类型 /// 对象 /// 转换类型后的对象 + [Obsolete("Not useful anymore")] public static T? As(this ICastService service) where T : class { diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs index cc6a885d..db4f9b19 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/DependencyInjection.cs @@ -51,8 +51,13 @@ internal static class DependencyInjection CultureOptions cultureOptions = serviceProvider.GetRequiredService(); cultureOptions.SystemCulture = CultureInfo.CurrentCulture; + ILogger logger = serviceProvider.GetRequiredService>(); + logger.LogDebug("System Culture: {System}", cultureOptions.SystemCulture); + CultureInfo cultureInfo = cultureOptions.CurrentCulture; + logger.LogDebug("Current Culture: {Current}", cultureInfo); + CultureInfo.DefaultThreadCurrentCulture = cultureInfo; CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; CultureInfo.CurrentCulture = cultureInfo; @@ -63,6 +68,7 @@ internal static class DependencyInjection SH.Culture = cultureInfo; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void InitializeConsoleWindow(this IServiceProvider serviceProvider) { _ = serviceProvider.GetRequiredService(); diff --git a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/IocConfiguration.cs b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/IocConfiguration.cs index 13e7329d..199f9d11 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/IocConfiguration.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/DependencyInjection/IocConfiguration.cs @@ -47,17 +47,13 @@ internal static class IocConfiguration { if (context.Database.GetPendingMigrations().Any()) { -#if DEBUG System.Diagnostics.Debug.WriteLine("[Database] Performing AppDbContext Migrations"); -#endif context.Database.Migrate(); } } builder -#if DEBUG .EnableSensitiveDataLogging() -#endif .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) .UseSqlite(sqlConnectionString); } diff --git a/src/Snap.Hutao/Snap.Hutao/Core/Diagnostics/MeasureExecutionToken.cs b/src/Snap.Hutao/Snap.Hutao/Core/Diagnostics/MeasureExecutionToken.cs index 0ea5a163..4cc4692b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/Diagnostics/MeasureExecutionToken.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/Diagnostics/MeasureExecutionToken.cs @@ -17,6 +17,6 @@ internal readonly struct MeasureExecutionToken : IDisposable public void Dispose() { - logger.LogInformation("{Caller} toke {Time} ms", callerName, stopwatch.GetElapsedTime().TotalMilliseconds); + logger.LogDebug("{Caller} toke {Time} ms", callerName, stopwatch.GetElapsedTime().TotalMilliseconds); } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/DatabaseCorruptedException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/DatabaseCorruptedException.cs index c015352d..f66043bf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/DatabaseCorruptedException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/DatabaseCorruptedException.cs @@ -7,6 +7,7 @@ namespace Snap.Hutao.Core.ExceptionService; /// 数据库损坏异常 /// [HighQuality] +[Obsolete("Use HutaoException instead")] internal sealed class DatabaseCorruptedException : Exception { /// diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/RuntimeEnvironmentException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/RuntimeEnvironmentException.cs index b96e87b3..a9c82957 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/RuntimeEnvironmentException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/RuntimeEnvironmentException.cs @@ -8,6 +8,7 @@ namespace Snap.Hutao.Core.ExceptionService; /// 用户的计算机中的某些设置不符合要求 /// [HighQuality] +[Obsolete("Use HutaoException instead")] internal sealed class RuntimeEnvironmentException : Exception { /// diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/ThrowHelper.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/ThrowHelper.cs index 263a6378..38b1fec1 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/ThrowHelper.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/ThrowHelper.cs @@ -13,6 +13,7 @@ namespace Snap.Hutao.Core.ExceptionService; /// [HighQuality] [System.Diagnostics.StackTraceHidden] +[Obsolete("Use HutaoException instead")] internal static class ThrowHelper { [DoesNotReturn] diff --git a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs index 934753e1..d8de5ec5 100644 --- a/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs +++ b/src/Snap.Hutao/Snap.Hutao/Core/ExceptionService/UserdataCorruptedException.cs @@ -7,6 +7,7 @@ namespace Snap.Hutao.Core.ExceptionService; /// 用户数据损坏异常 /// [HighQuality] +[Obsolete("Use HutaoException instead")] internal sealed class UserdataCorruptedException : Exception { ///