|
12 | 12 | using System; |
13 | 13 | using System.Collections.Generic; |
14 | 14 | using System.IO; |
| 15 | +using System.Linq; |
| 16 | +using System.Net; |
15 | 17 | using System.Net.Http; |
16 | 18 | using System.Security.Cryptography; |
17 | 19 | using System.Text.Json.Serialization; |
@@ -375,6 +377,20 @@ await LoadMetadataFile<StarRailAssetJsonMetadata>(instance, |
375 | 377 | aDirRawRes, |
376 | 378 | token); |
377 | 379 |
|
| 380 | + // Perform URL test & swap for Audio and Video |
| 381 | + await baseUrl.TestAndSwapUrlAsync(client, |
| 382 | + mainUrlAsbAlt.CombineURLFromString("AudioBlock"), |
| 383 | + () => metadataAudioV?.DataList.FirstOrDefault(x => x.Filename?.EndsWith(".pck", StringComparison.OrdinalIgnoreCase) ?? false), |
| 384 | + context => context.Audio, |
| 385 | + (context, replace) => context.Audio = replace, |
| 386 | + token); |
| 387 | + await baseUrl.TestAndSwapUrlAsync(client, |
| 388 | + mainUrlAsbAlt.CombineURLFromString("Video"), |
| 389 | + () => metadataVideoV?.DataList.FirstOrDefault(x => x.Filename?.EndsWith(".usm", StringComparison.OrdinalIgnoreCase) ?? false), |
| 390 | + context => context.Video, |
| 391 | + (context, replace) => context.Video = replace, |
| 392 | + token); |
| 393 | + |
378 | 394 | return new StarRailPersistentRefResult |
379 | 395 | { |
380 | 396 | BaseDirs = baseDirs, |
@@ -599,19 +615,65 @@ public AssetBaseDirs() : this("", "", "", "", "", "", "") |
599 | 615 | public class AssetBaseUrls |
600 | 616 | { |
601 | 617 | public required Dictionary<string, string> GatewayKvp { get; set; } |
602 | | - public required string DesignData { get; set; } |
| 618 | + public required string DesignData { get; init; } |
603 | 619 | public required string Archive { get; set; } |
604 | 620 | public required string Audio { get; set; } |
605 | 621 | public required string AsbBlock { get; set; } |
606 | 622 | public required string AsbBlockPersistent { get; set; } |
607 | | - public required string NativeData { get; set; } |
| 623 | + public required string NativeData { get; init; } |
608 | 624 | public required string Video { get; set; } |
609 | | - public required string RawRes { get; set; } |
| 625 | + public required string RawRes { get; init; } |
610 | 626 |
|
611 | | - public string? CacheLua { get; set; } |
612 | | - public string? CacheIFix { get; set; } |
| 627 | + public string? CacheLua { get; init; } |
| 628 | + public string? CacheIFix { get; init; } |
613 | 629 |
|
614 | 630 | public void SwapAsbPersistentUrl() => (AsbBlock, AsbBlockPersistent) = (AsbBlockPersistent, AsbBlock); |
| 631 | + |
| 632 | + public async Task TestAndSwapUrlAsync( |
| 633 | + HttpClient client, |
| 634 | + string urlBaseAlt, |
| 635 | + Func<StarRailAssetGenericFileInfo?> testAssetSelector, |
| 636 | + Func<AssetBaseUrls, string> propertySelector, |
| 637 | + Action<AssetBaseUrls, string> propertyModifier, |
| 638 | + CancellationToken token) |
| 639 | + { |
| 640 | + if (testAssetSelector() is not {} firstAssetToTest || |
| 641 | + firstAssetToTest.Filename == null) |
| 642 | + { |
| 643 | + return; |
| 644 | + } |
| 645 | + |
| 646 | + bool isRetry = false; |
| 647 | + string rootUrlToTest = propertySelector(this); |
| 648 | + |
| 649 | + Test: |
| 650 | + string testUrl = rootUrlToTest.CombineURLFromString(firstAssetToTest.Filename); |
| 651 | + UrlStatus testUrlStatus = await client.GetCachedUrlStatus(testUrl, token); |
| 652 | + |
| 653 | + switch (testUrlStatus.IsSuccessStatusCode) |
| 654 | + { |
| 655 | + // If status is success and retry is requested, then swap the Audio property |
| 656 | + case true when isRetry: |
| 657 | + propertyModifier(this, urlBaseAlt); |
| 658 | + return; |
| 659 | + // If status still fails and retry is requested, throw. |
| 660 | + case false when isRetry: |
| 661 | + throw new |
| 662 | + HttpRequestException($"Both Base URLs: {Audio} or {urlBaseAlt} doesn't contain a correct location of the audio files.", |
| 663 | + null, |
| 664 | + testUrlStatus.StatusCode); |
| 665 | + } |
| 666 | + |
| 667 | + // If status is 404 (Not Found), start swapping the URL |
| 668 | + if (testUrlStatus is { IsSuccessStatusCode: false, StatusCode: HttpStatusCode.NotFound } && !isRetry) |
| 669 | + { |
| 670 | + isRetry = true; |
| 671 | + rootUrlToTest = urlBaseAlt; |
| 672 | + goto Test; |
| 673 | + } |
| 674 | + |
| 675 | + // If status is already successful, do nothing. |
| 676 | + } |
615 | 677 | } |
616 | 678 |
|
617 | 679 | public class AssetMetadata |
|
0 commit comments