Skip to content

Commit 011cbf3

Browse files
committed
Force Redirect to Sophon if Zip information is empty
1 parent 7355144 commit 011cbf3

File tree

8 files changed

+93
-33
lines changed

8 files changed

+93
-33
lines changed

CollapseLauncher/Classes/GameManagement/Versioning/GameVersionBase.GameState.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,11 @@ public virtual async ValueTask<List<RegionResourcePlugin>> CheckPluginUpdate(str
528528
// If all not passed, then return null.
529529
return null;
530530
}
531+
532+
public virtual bool IsForceRedirectToSophon()
533+
{
534+
return GamePreset.GameLauncherApi?.IsForceRedirectToSophon ?? false;
535+
}
531536
#endregion
532537
}
533538
}

CollapseLauncher/Classes/Helper/LauncherApiLoader/HoYoPlay/HoYoPlayLauncherApiLoader.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,6 @@ void AfterExecute(Task action)
156156
ConvertPackageResources(sophonResourceData, hypResourceResponse?.Data?.LauncherPackages);
157157

158158
LauncherGameResource = sophonResourcePropRoot;
159-
160-
PerformDebugRoutines();
161159
}
162160
}
163161

CollapseLauncher/Classes/Helper/LauncherApiLoader/ILauncherApi.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,26 @@
66
using System.Threading;
77
using System.Threading.Tasks;
88
// ReSharper disable UnusedMemberInSuper.Global
9+
// ReSharper disable IdentifierTypo
910

1011
#nullable enable
1112
namespace CollapseLauncher.Helper.LauncherApiLoader
1213
{
1314
public interface ILauncherApi : IDisposable
1415
{
15-
bool IsLoadingCompleted { get; }
16-
string? GameBackgroundImg { get; }
17-
string? GameBackgroundImgLocal { get; set; }
18-
string? GameName { get; }
19-
string? GameRegion { get; }
20-
string? GameNameTranslation { get; }
21-
string? GameRegionTranslation { get; }
22-
HoYoPlayGameInfoField? LauncherGameInfoField { get; }
23-
RegionResourceProp? LauncherGameResource { get; }
24-
LauncherGameNews? LauncherGameNews { get; }
25-
HttpClient? ApiGeneralHttpClient { get; }
26-
HttpClient? ApiResourceHttpClient { get; }
16+
bool IsLoadingCompleted { get; }
17+
bool IsForceRedirectToSophon { get; }
18+
string? GameBackgroundImg { get; }
19+
string? GameBackgroundImgLocal { get; set; }
20+
string? GameName { get; }
21+
string? GameRegion { get; }
22+
string? GameNameTranslation { get; }
23+
string? GameRegionTranslation { get; }
24+
HoYoPlayGameInfoField? LauncherGameInfoField { get; }
25+
RegionResourceProp? LauncherGameResource { get; }
26+
LauncherGameNews? LauncherGameNews { get; }
27+
HttpClient? ApiGeneralHttpClient { get; }
28+
HttpClient? ApiResourceHttpClient { get; }
2729
Task<bool> LoadAsync(OnLoadTaskAction? beforeLoadRoutine = null, OnLoadTaskAction? afterLoadRoutine = null,
2830
ActionOnTimeOutRetry? onTimeoutRoutine = null, ErrorLoadRoutineDelegate? errorLoadRoutine = null,
2931
CancellationToken token = default);

CollapseLauncher/Classes/Helper/LauncherApiLoader/LauncherApiBase.cs

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
using System.Threading;
1212
using System.Threading.Tasks;
1313
using Hi3Helper.SentryHelper;
14-
using Hi3Helper.Sophon.Structs;
1514
using System.Net.Http;
1615
using System.Net;
1716
using System.Net.Http.Json;
1817
using System.Runtime.CompilerServices;
1918
using System.Linq;
19+
using System.Collections.Generic;
2020
// ReSharper disable PartialTypeWithSinglePart
2121
// ReSharper disable IdentifierTypo
2222
// ReSharper disable StringLiteralTypo
@@ -36,11 +36,12 @@ internal partial class LauncherApiBase : ILauncherApi
3636
public const int ExecutionTimeoutAttempt = 5;
3737
protected PresetConfig? PresetConfig { get; }
3838

39-
public bool IsLoadingCompleted { get; private set; }
40-
public string? GameBackgroundImg { get => LauncherGameNews?.Content?.Background?.BackgroundImg; }
41-
public string? GameBackgroundImgLocal { get; set; }
42-
public string? GameName { get; init; }
43-
public string? GameRegion { get; init; }
39+
public bool IsLoadingCompleted { get; private set; }
40+
public bool IsForceRedirectToSophon { get; private set; }
41+
public string? GameBackgroundImg { get => LauncherGameNews?.Content?.Background?.BackgroundImg; }
42+
public string? GameBackgroundImgLocal { get; set; }
43+
public string? GameName { get; init; }
44+
public string? GameRegion { get; init; }
4445

4546
public string? GameNameTranslation =>
4647
InnerLauncherConfig.GetGameTitleRegionTranslationString(GameName, Locale.Lang._GameClientTitles);
@@ -118,9 +119,11 @@ protected LauncherApiBase(PresetConfig presetConfig, string gameName, string gam
118119
ApiResourceHttpClient = apiResourceHttpBuilder.Create();
119120
}
120121

121-
public async Task<bool> LoadAsync(OnLoadTaskAction? beforeLoadRoutine, OnLoadTaskAction? afterLoadRoutine,
122-
ActionOnTimeOutRetry? onTimeoutRoutine, ErrorLoadRoutineDelegate? errorLoadRoutine,
123-
CancellationToken token)
122+
public async Task<bool> LoadAsync(OnLoadTaskAction? beforeLoadRoutine,
123+
OnLoadTaskAction? afterLoadRoutine,
124+
ActionOnTimeOutRetry? onTimeoutRoutine,
125+
ErrorLoadRoutineDelegate? errorLoadRoutine,
126+
CancellationToken token)
124127
{
125128
_ = beforeLoadRoutine?.Invoke(token) ?? Task.CompletedTask;
126129

@@ -145,7 +148,7 @@ public async Task<bool> LoadAsync(OnLoadTaskAction? beforeLoadRoutine, OnLoa
145148
}
146149

147150
protected virtual async Task LoadAsyncInner(ActionOnTimeOutRetry? onTimeoutRoutine,
148-
CancellationToken token)
151+
CancellationToken token)
149152
{
150153
// 2025-05-05: As per now, the Sophon resource information requires to be fetched first.
151154
// This is mandatory due to latest Genshin Impact changes which removes zip
@@ -161,17 +164,57 @@ await Task.WhenAll(LoadLauncherGameResource(onTimeoutRoutine, token),
161164

162165
protected virtual void InitializeFakeVersionInfo()
163166
{
164-
if (LauncherGameResourceSophon == null)
167+
if (LauncherGameResource?.data == null)
168+
{
169+
return;
170+
}
171+
172+
HoYoPlayGameInfoBranch? gameBranch = LauncherGameResourceSophon?.GameInfoData?.GameBranchesInfo?
173+
.FirstOrDefault(x => x.GameInfo?.BizName?.Equals(PresetConfig?.LauncherBizName) ?? false);
174+
175+
if (gameBranch == null)
176+
{
177+
return;
178+
}
179+
180+
var branchPreloadField = gameBranch.GamePreloadField;
181+
var branchBaseField = gameBranch.GameMainField;
182+
183+
if (branchPreloadField != null)
184+
{
185+
LauncherGameResource.data.pre_download_game ??= new RegionResourceLatest();
186+
AddFakeVersionInfo(branchPreloadField, LauncherGameResource.data.pre_download_game);
187+
}
188+
189+
if (branchBaseField == null)
165190
{
166191
return;
167192
}
168193

169-
HoYoPlayGameInfoBranch? gameBranch = LauncherGameResourceSophon.GameInfoData?.GameBranchesInfo?
170-
.FirstOrDefault(x => x.GameInfo?.BizName?.Equals(PresetConfig?.LauncherBizName) ?? false);
194+
LauncherGameResource.data.game ??= new RegionResourceLatest();
195+
AddFakeVersionInfo(branchBaseField, LauncherGameResource.data.game);
196+
IsForceRedirectToSophon = true;
197+
}
198+
199+
protected virtual void AddFakeVersionInfo(HoYoPlayGameInfoBranchField branchField, RegionResourceLatest region)
200+
{
201+
region.latest ??= new RegionResourceVersion();
202+
region.latest.version = branchField.Tag;
203+
204+
region.diffs ??= [];
205+
206+
HashSet<string> existingDiffsVer = new(region.diffs.Select(x => x.version)!);
207+
foreach (var versionTags in (branchField.DiffTags ?? []).Where(x => !existingDiffsVer.Contains(x)))
208+
{
209+
region.diffs.Add(new RegionResourceVersion
210+
{
211+
version = versionTags
212+
});
213+
}
171214
}
172215

173216
protected virtual async Task LoadLauncherGameResourceSophon(ActionOnTimeOutRetry? onTimeoutRoutine,
174-
CancellationToken token)
217+
CancellationToken token)
175218
{
176219
EnsurePresetConfigNotNull();
177220

@@ -188,6 +231,7 @@ protected virtual async Task LoadLauncherGameResourceSophon(ActionOnTimeOutRetry
188231
PresetConfig.LauncherBizName!,
189232
false,
190233
token) ?? Task.CompletedTask);
234+
sophonUrls?.ResetAssociation(); // Reset association so it won't conflict with preload/update/install activity
191235

192236
ActionTimeoutTaskAwaitableCallback<HoYoPlayLauncherGameInfo?> launcherSophonBranchCallback =
193237
innerToken =>

CollapseLauncher/Classes/Helper/Metadata/PresetConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ public class SophonChunkUrls
9898
[JsonConverter(typeof(ServeV3StringConverter))]
9999
public string? SdkUrl { get; set; }
100100

101+
public bool ResetAssociation() => IsReassociated = false;
102+
101103
public Task EnsureReassociated(HttpClient client, string? branchUrl, string bizName, bool isPreloadForPatch, CancellationToken token)
102104
{
103105
if (IsReassociated)

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ protected bool _isSophonPreloadCompleted
8383

8484
#region Public Virtual Properties
8585
public virtual bool IsUseSophon =>
86-
GameVersionManager.GamePreset.LauncherResourceChunksURL != null
86+
GameVersionManager.IsForceRedirectToSophon() ||
87+
(GameVersionManager.GamePreset.LauncherResourceChunksURL != null
8788
&& !File.Exists(Path.Combine(GamePath, "@DisableSophon"))
8889
&& !_canDeltaPatch && !_forceIgnoreDeltaPatch
89-
&& LauncherConfig.GetAppConfigValue("IsEnableSophon").ToBool();
90+
&& LauncherConfig.GetAppConfigValue("IsEnableSophon").ToBool());
9091
#endregion
9192

9293
#region Sophon Verification Methods

CollapseLauncher/Classes/InstallManagement/Genshin/GenshinInstall.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,10 @@ namespace CollapseLauncher.InstallManager.Genshin
2727
internal sealed partial class GenshinInstall : InstallManagerBase
2828
{
2929
#region Override Properties
30-
3130
protected override int _gameVoiceLanguageID => GameVersionManager.GamePreset.GetVoiceLanguageID();
32-
3331
#endregion
3432

3533
#region Properties
36-
3734
protected override string _gameAudioLangListPath
3835
{
3936
get
@@ -74,6 +71,12 @@ public GenshinInstall(UIElement parentUI, IGameVersion GameVersionManager)
7471
#nullable enable
7572
public override async ValueTask<bool> IsPreloadCompleted(CancellationToken token)
7673
{
74+
// If it's forcely redirected to sophon, check the preload using sophon
75+
if (GameVersionManager.IsForceRedirectToSophon())
76+
{
77+
return await base.IsPreloadCompleted(token);
78+
}
79+
7780
// Get the primary file first check
7881
List<RegionResourceVersion>? resource = GameVersionManager.GetGamePreloadZip();
7982

CollapseLauncher/Classes/Interfaces/IGameVersionCheck.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ internal interface IGameVersion
130130
/// </summary>
131131
bool IsGameHasDeltaPatch();
132132

133+
/// <summary>
134+
/// Check if the game installation is forcely redirected to Sophon.
135+
/// </summary>
136+
bool IsForceRedirectToSophon();
137+
133138
/// <summary>
134139
/// Returns the state of the game.
135140
/// </summary>

0 commit comments

Comments
 (0)