diff --git a/src/MaaWpfGui/Services/StageManager.cs b/src/MaaWpfGui/Services/StageManager.cs index b36c1142ab..16497f9803 100644 --- a/src/MaaWpfGui/Services/StageManager.cs +++ b/src/MaaWpfGui/Services/StageManager.cs @@ -91,14 +91,12 @@ public class StageManager } } - var webStages = await LoadWebStages(); - if (webStages is null) + var loaded = await LoadWebStages(); + if (!loaded) { return; } - MergePermanentAndActivityStages(webStages); - _ = Execute.OnUIThreadAsync(() => { var growlInfo = new GrowlInfo { IsCustom = true, @@ -123,9 +121,9 @@ public class StageManager return clientType; } - private static JObject LoadLocalStages() + private static JObject? LoadLocalStages() { - JObject activity = Instances.MaaApiService.LoadApiCache(StageApi); + JObject? activity = Instances.MaaApiService.LoadApiCache(StageApi); return activity; } @@ -137,7 +135,7 @@ public class StageManager const string AllFileDownloadCompleteFile = "allFileDownloadComplete.json"; JObject localLastUpdatedJson = Instances.MaaApiService.LoadApiCache(StageAndTasksUpdateTime); JObject allFileDownloadCompleteJson = Instances.MaaApiService.LoadApiCache(AllFileDownloadCompleteFile); - JObject webLastUpdatedJson = await Instances.MaaApiService.RequestMaaApiWithCache(StageAndTasksUpdateTime).ConfigureAwait(false); + var (_, webLastUpdatedJson) = await Instances.MaaApiService.RequestMaaApiWithCache(StageAndTasksUpdateTime).ConfigureAwait(false); if (localLastUpdatedJson?["timestamp"] == null || webLastUpdatedJson?["timestamp"] == null) { @@ -151,7 +149,7 @@ public class StageManager } */ - private static async Task LoadWebStages() + private async Task LoadWebStages() { var clientType = GetClientType(); @@ -160,9 +158,10 @@ public class StageManager await Task.WhenAll(activityTask, tasksTask); - var activityJson = await activityTask; - var tasksJson = await tasksTask; + var (activityCached, activityJson) = await activityTask; + var (taskCached, tasksJson) = await tasksTask; JObject? globalTasksJson = null; + bool globalTasksCached = true; if (clientType != ClientType.Official && tasksJson != null) { var tasksPath = "resource/global/" + clientType + '/' + TasksApi; @@ -170,23 +169,31 @@ public class StageManager // Download the client specific resources only when the Official ones are successfully downloaded so that the client specific resource version is the actual version // TODO: There may be an issue when the CN resource is loaded from cache (e.g. network down) while global resource is downloaded (e.g. network up again) // var tasksJsonClient = fromWeb ? WebService.RequestMaaApiWithCache(tasksPath) : WebService.RequestMaaApiWithCache(tasksPath); - globalTasksJson = await Instances.MaaApiService.RequestMaaApiWithCache(tasksPath, false); + (globalTasksCached, globalTasksJson) = await Instances.MaaApiService.RequestMaaApiWithCache(tasksPath, false); } if (activityJson is null || tasksJson is null) { - return null; + return false; } if (clientType != ClientType.Official && globalTasksJson is null) { - return null; + return false; } - await Task.Run(() => { - _ = Instances.AsstProxy.LoadResourceWhenIdleAsync(); - }); - return activityJson; + if (!taskCached || !globalTasksCached) + { + await Task.Run(() => { + _ = Instances.AsstProxy.LoadResourceWhenIdleAsync(); + }); + } + + if (!activityCached) + { + MergePermanentAndActivityStages(activityJson); + } + return true; } private void MergePermanentAndActivityStages(JObject? activity) diff --git a/src/MaaWpfGui/Services/Web/IMaaApiService.cs b/src/MaaWpfGui/Services/Web/IMaaApiService.cs index b43fb6e050..b64c805606 100644 --- a/src/MaaWpfGui/Services/Web/IMaaApiService.cs +++ b/src/MaaWpfGui/Services/Web/IMaaApiService.cs @@ -10,7 +10,7 @@ // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY // - +#nullable enable using System.Threading.Tasks; using Newtonsoft.Json.Linq; @@ -18,7 +18,7 @@ namespace MaaWpfGui.Services.Web; public interface IMaaApiService { - Task RequestMaaApiWithCache(string api, bool allowFallbackToCache = true); + Task<(bool Cached, JObject? Response)> RequestMaaApiWithCache(string api, bool allowFallbackToCache = true); - JObject LoadApiCache(string api); + JObject? LoadApiCache(string api); } diff --git a/src/MaaWpfGui/Services/Web/MaaApiService.cs b/src/MaaWpfGui/Services/Web/MaaApiService.cs index 8cd2f030dc..9dcabe018f 100644 --- a/src/MaaWpfGui/Services/Web/MaaApiService.cs +++ b/src/MaaWpfGui/Services/Web/MaaApiService.cs @@ -26,67 +26,69 @@ public class MaaApiService : IMaaApiService { private static readonly string CacheDir = PathsHelper.CacheDir; - public async Task RequestMaaApiWithCache(string api, bool allowFallbackToCache = true) + public async Task<(bool Cached, JObject? Response)> RequestMaaApiWithCache(string api, bool allowFallbackToCache = true) { return await RequestWithFallback(api, MaaUrls.MaaApi, MaaUrls.MaaApi2, allowFallbackToCache); } - private async Task RequestWithFallback(string api, string primaryBaseUrl, string? fallbackBaseUrl = null, bool allowFallbackToCache = true) + private async Task<(bool Cached, JObject? Response)> RequestWithFallback(string api, string primaryBaseUrl, string? fallbackBaseUrl = null, bool allowFallbackToCache = true) { - var json = await TryRequest(api, primaryBaseUrl, allowFallbackToCache); - if (json != null || string.IsNullOrEmpty(fallbackBaseUrl)) + var result = await TryRequest(api, primaryBaseUrl, allowFallbackToCache); + if (result.Response != null || string.IsNullOrEmpty(fallbackBaseUrl)) { - return json; + return result; } return await TryRequest(api, fallbackBaseUrl, allowFallbackToCache); } - private async Task TryRequest(string api, string baseUrl, bool allowFallbackToCache = true) + private async Task<(bool Cached, JObject? Response)> TryRequest(string api, string baseUrl, bool allowFallbackToCache = true) { var url = baseUrl + api; - var cache = Path.Combine(CacheDir, api); - - var response = await ETagCache.FetchResponseWithEtag(url, !File.Exists(cache)); - if (response == null) + var cachePath = Path.Combine(CacheDir, api); + var response = await ETagCache.FetchResponseWithEtag(url, !File.Exists(cachePath)); + if (response?.StatusCode == System.Net.HttpStatusCode.NotModified) { - return allowFallbackToCache ? LoadApiCache(api) : null; + var cache = LoadApiCache(api); + return (cache != null, cache); } - if (response.StatusCode == System.Net.HttpStatusCode.NotModified) + if (response == null || response.StatusCode != System.Net.HttpStatusCode.OK) { - return LoadApiCache(api); - } + if (!allowFallbackToCache) + { + return (false, null); + } - if (response.StatusCode != System.Net.HttpStatusCode.OK) - { - return allowFallbackToCache ? LoadApiCache(api) : null; + var cache = LoadApiCache(api); + return (cache != null, cache); } var body = await HttpResponseHelper.GetStringAsync(response); if (string.IsNullOrEmpty(body)) { - return LoadApiCache(api); + var cache = LoadApiCache(api); + return (cache != null, cache); } try { var json = (JObject?)JsonConvert.DeserializeObject(body); - string? directoryPath = Path.GetDirectoryName(cache); + string? directoryPath = Path.GetDirectoryName(cachePath); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath!); } - await File.WriteAllTextAsync(cache, body); + await File.WriteAllTextAsync(cachePath, body); ETagCache.Set(response, url); - return json; + return (false, json); } catch { - return null; + return (false, null); } } diff --git a/src/MaaWpfGui/ViewModels/Dialogs/VersionUpdateDialogViewModel.cs b/src/MaaWpfGui/ViewModels/Dialogs/VersionUpdateDialogViewModel.cs index c1b3443bd6..901ab278e8 100644 --- a/src/MaaWpfGui/ViewModels/Dialogs/VersionUpdateDialogViewModel.cs +++ b/src/MaaWpfGui/ViewModels/Dialogs/VersionUpdateDialogViewModel.cs @@ -880,7 +880,7 @@ public class VersionUpdateDialogViewModel : Screen private async Task CheckUpdateByMaaApi() { - JObject json = await Instances.MaaApiService.RequestMaaApiWithCache(MaaUpdateApi); + var (_, json) = await Instances.MaaApiService.RequestMaaApiWithCache(MaaUpdateApi); if (json is null) { @@ -908,7 +908,7 @@ public class VersionUpdateDialogViewModel : Screen private async Task GetVersionDetailsByMaaApi(string versionType) { - var json = await Instances.MaaApiService.RequestMaaApiWithCache($"version/{versionType}.json", false); + var (_, json) = await Instances.MaaApiService.RequestMaaApiWithCache($"version/{versionType}.json", false); if (json is null) { return CheckUpdateRetT.NetworkError;