Skip to content

Commit 7a553be

Browse files
committed
Adding fallback to perform full update if no incremental update
1 parent fd4a680 commit 7a553be

File tree

4 files changed

+160
-42
lines changed

4 files changed

+160
-42
lines changed

CollapseLauncher/Classes/InstallManagement/BaseClass/InstallManagerBase.Sophon.cs

Lines changed: 147 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// ReSharper disable GrammarMistakeInComment
88

99
using CollapseLauncher.Dialogs;
10+
using CollapseLauncher.Extension;
1011
using CollapseLauncher.Helper;
1112
using Hi3Helper;
1213
using Hi3Helper.Data;
@@ -15,6 +16,7 @@
1516
using Hi3Helper.Shared.Region;
1617
using Hi3Helper.Sophon;
1718
using Hi3Helper.Sophon.Structs;
19+
using Microsoft.UI.Xaml.Controls;
1820
using System;
1921
using System.Collections.Concurrent;
2022
using System.Collections.Generic;
@@ -108,7 +110,7 @@ protected virtual void CleanupTempSophonVerifiedFiles()
108110
#endregion
109111

110112
#region Sophon Download and Install/Update/Preload Methods
111-
public virtual async Task StartPackageInstallSophon(GameInstallStateEnum gameState)
113+
public virtual async Task StartPackageInstallSophon(GameInstallStateEnum gameState, bool fallbackFromUpdate = false)
112114
{
113115
// Set the flag to false
114116
_isSophonDownloadCompleted = false;
@@ -199,39 +201,84 @@ await _gameVersionManager.GamePreset
199201

200202
// Add the tag query to the Url
201203
requestedUrl += $"&tag={requestedVersion.ToString()}";
202-
#endif
203-
204-
// Initialize the info pair list
205-
var sophonInfoPairList = new List<SophonChunkManifestInfoPair>();
206-
207-
// Get the info pair based on info provided above (for main game file)
208-
var sophonMainInfoPair = await
209-
SophonManifest.CreateSophonChunkManifestInfoPair(
210-
httpClient,
211-
requestedUrl,
212-
"game",
213-
_token.Token);
204+
#endif
214205

215-
// Ensure that the manifest is ordered based on _gameVoiceLanguageLocaleIdOrdered
216-
RearrangeSophonDataLocaleOrder(sophonMainInfoPair.OtherSophonData);
217-
218-
// Add the manifest to the pair list
219-
sophonInfoPairList.Add(sophonMainInfoPair);
206+
try
207+
{
208+
// Initialize the info pair list
209+
var sophonInfoPairList = new List<SophonChunkManifestInfoPair>();
210+
211+
// Get the info pair based on info provided above (for main game file)
212+
var sophonMainInfoPair = await
213+
SophonManifest.CreateSophonChunkManifestInfoPair(
214+
httpClient,
215+
requestedUrl,
216+
"game",
217+
_token.Token);
218+
219+
// Ensure that the manifest is ordered based on _gameVoiceLanguageLocaleIdOrdered
220+
RearrangeSophonDataLocaleOrder(sophonMainInfoPair.OtherSophonData);
221+
222+
// Add the manifest to the pair list
223+
sophonInfoPairList.Add(sophonMainInfoPair);
224+
225+
List<string> voLanguageList =
226+
GetSophonLanguageDisplayDictFromVoicePackList(sophonMainInfoPair.OtherSophonData);
227+
228+
// Get Audio Choices first.
229+
// If the fallbackFromUpdate flag is set, then don't show the dialog and instead
230+
// use the default language (ja-jp) as the fallback and read the existing audio_lang file
231+
List<int> addedVo;
232+
int setAsDefaultVo = GetSophonLocaleCodeIndex(
233+
sophonMainInfoPair.OtherSophonData,
234+
"ja-jp"
235+
);
236+
237+
if (fallbackFromUpdate)
238+
{
239+
addedVo = [];
240+
if (!File.Exists(_gameAudioLangListPathStatic))
241+
{
242+
addedVo.Add(setAsDefaultVo);
243+
}
244+
else
245+
{
246+
string[] voLangList = await File.ReadAllLinesAsync(_gameAudioLangListPathStatic);
247+
foreach (string voLang in voLangList)
248+
{
249+
string? voLocaleId = GetLanguageLocaleCodeByLanguageString(
250+
voLang
251+
#if DEBUG
252+
, true
253+
#endif
254+
);
255+
256+
if (string.IsNullOrEmpty(voLocaleId))
257+
{
258+
continue;
259+
}
220260

221-
List<string> voLanguageList =
222-
GetSophonLanguageDisplayDictFromVoicePackList(sophonMainInfoPair.OtherSophonData);
261+
int voLocaleIndex = GetSophonLocaleCodeIndex(
262+
sophonMainInfoPair.OtherSophonData,
263+
voLocaleId
264+
);
265+
addedVo.Add(voLocaleIndex);
266+
}
223267

224-
// Get Audio Choices first
225-
(List<int> addedVo, int setAsDefaultVo) =
226-
await SimpleDialogs.Dialog_ChooseAudioLanguageChoice(
227-
voLanguageList,
228-
GetSophonLocaleCodeIndex(
229-
sophonMainInfoPair.OtherSophonData,
230-
"ja-jp"
231-
));
268+
if (addedVo.Count == 0)
269+
{
270+
addedVo.Add(setAsDefaultVo);
271+
}
272+
}
273+
}
274+
else
275+
{
276+
(addedVo, setAsDefaultVo) =
277+
await SimpleDialogs.Dialog_ChooseAudioLanguageChoice(
278+
voLanguageList,
279+
setAsDefaultVo);
280+
}
232281

233-
try
234-
{
235282
if (addedVo == null || setAsDefaultVo < 0)
236283
{
237284
throw new TaskCanceledException();
@@ -437,7 +484,6 @@ private async Task<List<SophonAsset>> GetSophonAssetListFromPair(
437484
return sophonAssetList;
438485
}
439486

440-
441487
public virtual async Task StartPackageUpdateSophon(GameInstallStateEnum gameState, bool isPreloadMode)
442488
{
443489
// Set the flag to false
@@ -513,8 +559,53 @@ await _gameVersionManager.GamePreset
513559
SophonDownloadSpeedLimiter.CreateInstance(LauncherConfig.DownloadSpeedLimitCached);
514560

515561
// Add base game diff data
516-
await AddSophonDiffAssetsToList(httpClient, requestedBaseUrlFrom, requestedBaseUrlTo,
517-
sophonUpdateAssetList, "game", downloadSpeedLimiter);
562+
bool isSuccess = await AddSophonDiffAssetsToList(
563+
httpClient,
564+
requestedBaseUrlFrom,
565+
requestedBaseUrlTo,
566+
sophonUpdateAssetList,
567+
"game",
568+
downloadSpeedLimiter);
569+
570+
// If it doesn't success to get the base diff, then fallback to actually download the whole game
571+
if (!isSuccess)
572+
{
573+
Logger.LogWriteLine($"The current game version: {requestedVersionFrom.ToString()} is too obsolete and incremental update is unavailable. Falling back to full update", LogType.Warning, true);
574+
575+
// Spawn the confirmation dialog
576+
ContentDialogResult fallbackResultConfirm = await SimpleDialogs.SpawnDialog(
577+
Locale.Lang._Dialogs.SophonIncrementUpdateUnavailTitle,
578+
new TextBlock
579+
{
580+
TextWrapping = Microsoft.UI.Xaml.TextWrapping.Wrap
581+
}
582+
.AddTextBlockLine(string.Format(Locale.Lang._Dialogs.SophonIncrementUpdateUnavailSubtitle1, requestedVersionFrom.ToString()))
583+
.AddTextBlockLine(Locale.Lang._Dialogs.SophonIncrementUpdateUnavailSubtitle2, Microsoft.UI.Text.FontWeights.Bold)
584+
.AddTextBlockLine(Locale.Lang._Dialogs.SophonIncrementUpdateUnavailSubtitle3)
585+
.AddTextBlockNewLine(2)
586+
.AddTextBlockLine(
587+
string.Format(Locale.Lang._Dialogs.SophonIncrementUpdateUnavailSubtitle4,
588+
Locale.Lang._Misc.YesContinue,
589+
Locale.Lang._Misc.NoCancel),
590+
Microsoft.UI.Text.FontWeights.Bold,
591+
10),
592+
_parentUI,
593+
Locale.Lang._Misc.NoCancel,
594+
Locale.Lang._Misc.YesContinue,
595+
defaultButton: ContentDialogButton.Primary,
596+
dialogTheme: CustomControls.ContentDialogTheme.Warning);
597+
598+
// If cancelled, then throw
599+
if (ContentDialogResult.Primary != fallbackResultConfirm)
600+
{
601+
throw new TaskCanceledException("The full update routine has been cancelled by the user");
602+
}
603+
604+
// Otherwise, continue updating the entire game
605+
gameState = GameInstallStateEnum.NotInstalled;
606+
await StartPackageInstallSophon(gameState, true);
607+
return;
608+
}
518609

519610
// If the game has lang list path, then add it
520611
if (_gameAudioLangListPath != null)
@@ -749,20 +840,33 @@ await SimpleDialogs.Dialog_InsufficientDriveSpace(_parentUI, driveInfo.TotalFree
749840
#endregion
750841

751842
#region Sophon Asset Package Methods
752-
753-
private async Task AddSophonDiffAssetsToList(HttpClient httpClient,
754-
string requestedUrlFrom,
755-
string requestedUrlTo,
756-
List<SophonAsset> sophonPreloadAssetList,
757-
string matchingField,
758-
SophonDownloadSpeedLimiter downloadSpeedLimiter)
843+
private async Task<bool> AddSophonDiffAssetsToList(HttpClient httpClient,
844+
string requestedUrlFrom,
845+
string requestedUrlTo,
846+
List<SophonAsset> sophonPreloadAssetList,
847+
string matchingField,
848+
SophonDownloadSpeedLimiter downloadSpeedLimiter)
759849
{
760850
// Get the manifest pair for both previous (from) and next (to) version
761851
SophonChunkManifestInfoPair requestPairFrom = await SophonManifest
762852
.CreateSophonChunkManifestInfoPair(httpClient, requestedUrlFrom, matchingField, _token.Token);
763853
SophonChunkManifestInfoPair requestPairTo = await SophonManifest
764854
.CreateSophonChunkManifestInfoPair(httpClient, requestedUrlTo, matchingField, _token.Token);
765855

856+
// If the request pair source is not found, then return false
857+
if (!requestPairFrom.IsFound)
858+
{
859+
Logger.LogWriteLine($"Sophon manifest for source via URL: {requestedUrlFrom} is not found! Return message: {requestPairFrom.ReturnMessage} ({requestPairFrom.ReturnCode})", LogType.Warning, true);
860+
return false;
861+
}
862+
863+
// If the request pair target is not found, then return false
864+
if (!requestPairTo.IsFound)
865+
{
866+
Logger.LogWriteLine($"Sophon manifest for target via URL: {requestedUrlTo} is not found! Return message: {requestPairTo.ReturnMessage} ({requestPairTo.ReturnCode})", LogType.Warning, true);
867+
return false;
868+
}
869+
766870
// Ensure that the manifest is ordered based on _gameVoiceLanguageLocaleIdOrdered
767871
RearrangeSophonDataLocaleOrder(requestPairFrom.OtherSophonData);
768872
RearrangeSophonDataLocaleOrder(requestPairTo.OtherSophonData);
@@ -775,6 +879,9 @@ private async Task AddSophonDiffAssetsToList(HttpClient httpClie
775879
{
776880
sophonPreloadAssetList.Add(sophonAsset);
777881
}
882+
883+
// Return as success
884+
return true;
778885
}
779886

780887
private async Task AddSophonAdditionalVODiffAssetsToList(HttpClient httpClient,

Hi3Helper.Core/Lang/Locale/LangDialogs.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ public sealed partial class LangDialogs
177177

178178
public string DbGenerateUid_Title { get; set; } = LangFallback?._Dialogs.DbGenerateUid_Title;
179179
public string DbGenerateUid_Content { get; set; } = LangFallback?._Dialogs.DbGenerateUid_Content;
180+
public string SophonIncrementUpdateUnavailTitle { get; set; } = LangFallback?._Dialogs.SophonIncrementUpdateUnavailTitle;
181+
public string SophonIncrementUpdateUnavailSubtitle1 { get; set; } = LangFallback?._Dialogs.SophonIncrementUpdateUnavailSubtitle1;
182+
public string SophonIncrementUpdateUnavailSubtitle2 { get; set; } = LangFallback?._Dialogs.SophonIncrementUpdateUnavailSubtitle2;
183+
public string SophonIncrementUpdateUnavailSubtitle3 { get; set; } = LangFallback?._Dialogs.SophonIncrementUpdateUnavailSubtitle3;
184+
public string SophonIncrementUpdateUnavailSubtitle4 { get; set; } = LangFallback?._Dialogs.SophonIncrementUpdateUnavailSubtitle4;
180185
}
181186
}
182187
#endregion

Hi3Helper.Core/Lang/en_US.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,13 @@
995995
"CloseOverlay": "Close Overlay",
996996

997997
"DbGenerateUid_Title": "Are you sure you wish to change your user ID?",
998-
"DbGenerateUid_Content": "Changing the current user ID will cause the associated data to be lost if you lose it."
998+
"DbGenerateUid_Content": "Changing the current user ID will cause the associated data to be lost if you lose it.",
999+
1000+
"SophonIncrementUpdateUnavailTitle": "Incremental Update is Unavailable: Version is Too Obsolete!",
1001+
"SophonIncrementUpdateUnavailSubtitle1": "Your game version: {0}",
1002+
"SophonIncrementUpdateUnavailSubtitle2": " is too obsolete",
1003+
"SophonIncrementUpdateUnavailSubtitle3": " and incremental update for your version is not available. However, you could still update your game by re-downloading the entire thing from scratch.",
1004+
"SophonIncrementUpdateUnavailSubtitle4": "Click \"{0}\" to continue updating the entire thing or click \"{1}\" to cancel the process"
9991005
},
10001006

10011007
"_FileMigrationProcess": {

0 commit comments

Comments
 (0)