Skip to content

Commit a12a616

Browse files
committed
feat(config): Sync launcher config files after install and patch
After every SaveConfig() call, update launcherDownloadConfig.json so Kuro's official launcher always sees the correct installed version. Fields that belong to Kuro (appId, reUseVersion, state) are preserved from the existing file; only version is overwritten and isPreDownload is cleared. After a successful install or patch, write LocalGameResources.json from the resource index that was used for the operation. This mirrors the manifest Kuro's launcher maintains so both launchers stay consistent. Supporting model changes: - WuwaApiResponseResourceEntry: add optional fromFolder property, which appears in LocalGameResources.json entries. - WuwaApiResponseContext: register WuwaApiResponseResourceIndex for source-generated JSON serialisation.
1 parent b26c68a commit a12a616

5 files changed

Lines changed: 127 additions & 0 deletions

File tree

Hi3Helper.Plugin.Wuwa/Management/Api/WuwaApiResponse.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ namespace Hi3Helper.Plugin.Wuwa.Management.Api;
99
[JsonSerializable(typeof(WuwaApiResponseGameConfig))]
1010
[JsonSerializable(typeof(WuwaApiResponsePatchIndex))]
1111
[JsonSerializable(typeof(WuwaLauncherDownloadConfig))]
12+
[JsonSerializable(typeof(WuwaApiResponseResourceIndex))]
1213
public partial class WuwaApiResponseContext : JsonSerializerContext;

Hi3Helper.Plugin.Wuwa/Management/Api/WuwaApiResponseResourceIndex.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public class WuwaApiResponseResourceEntry
1818
[JsonPropertyName("md5")]
1919
public string? Md5 { get; set; }
2020

21+
[JsonPropertyName("fromFolder")]
22+
public string? FromFolder { get; set; }
23+
2124
[JsonPropertyName("size")]
2225
[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
2326
public ulong Size { get; set; }

Hi3Helper.Plugin.Wuwa/Management/WuwaGameInstaller.Install.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,17 @@ void DownloadBytesCallback(long delta)
600600
{
601601
SharedStatic.InstanceLogger.LogWarning("[WuwaGameInstaller::StartInstallCoreAsync] Failed to write app-game-config.json: {Err}", ex.Message);
602602
}
603+
604+
// Write LocalGameResources.json so Kuro's launcher recognises the installed files
605+
try
606+
{
607+
if (_owner.GameManager is WuwaGameManager gmRes)
608+
gmRes.TryWriteLocalGameResources(installPath, index);
609+
}
610+
catch (Exception ex)
611+
{
612+
SharedStatic.InstanceLogger.LogWarning("[WuwaGameInstaller::StartInstallCoreAsync] Failed to write LocalGameResources.json: {Err}", ex.Message);
613+
}
603614
}
604615
catch (Exception ex)
605616
{

Hi3Helper.Plugin.Wuwa/Management/WuwaGameInstaller.Patch.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,19 @@ await _owner.TryDownloadWholeFileWithFallbacksAsync(
16111611

16121612
manager.SaveConfig();
16131613

1614+
// Write LocalGameResources.json so Kuro's launcher recognises the updated files
1615+
try
1616+
{
1617+
var resourceIndex = await _owner.GetCachedIndexAsync(false, token).ConfigureAwait(false);
1618+
if (resourceIndex != null)
1619+
manager.TryWriteLocalGameResources(installPath, resourceIndex);
1620+
}
1621+
catch (Exception ex)
1622+
{
1623+
SharedStatic.InstanceLogger.LogWarning(
1624+
"[Patch::RunAsync] Failed to write LocalGameResources.json: {Err}", ex.Message);
1625+
}
1626+
16141627
currentProgressState = InstallProgressState.Completed;
16151628
ReportProgress();
16161629
SharedStatic.InstanceLogger.LogInformation(

Hi3Helper.Plugin.Wuwa/Management/WuwaGameManager.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,9 @@ public override void SaveConfig()
741741
SharedStatic.InstanceLogger.LogWarning(
742742
"[WuwaGameManager::SaveConfig] Failed to write app-game-config.json: {Exception}", ex);
743743
}
744+
745+
// Keep launcherDownloadConfig.json in sync with the version we just persisted.
746+
TryUpdateLauncherDownloadConfig(CurrentGameInstallPath, CurrentGameVersion.ToString());
744747
}
745748

746749
internal string GetInstallType()
@@ -758,6 +761,102 @@ internal string GetInstallType()
758761
return "unknown";
759762
}
760763

764+
/// <summary>
765+
/// Writes (or updates) <c>launcherDownloadConfig.json</c> in the game install directory
766+
/// with the supplied <paramref name="version"/>. If the file already exists its other
767+
/// fields (e.g. <c>appId</c>) are preserved; only <c>version</c> is changed.
768+
/// </summary>
769+
internal void TryUpdateLauncherDownloadConfig(string installPath, string version)
770+
{
771+
const string fileName = "launcherDownloadConfig.json";
772+
string configPath = Path.Combine(installPath, fileName);
773+
774+
// Start from any existing data so we preserve fields like appId.
775+
var cfg = new WuwaLauncherDownloadConfig
776+
{
777+
Version = version,
778+
ReUseVersion = string.Empty,
779+
State = string.Empty,
780+
IsPreDownload = false,
781+
};
782+
783+
if (File.Exists(configPath))
784+
{
785+
try
786+
{
787+
using var readFs = File.OpenRead(configPath);
788+
var existing = JsonSerializer.Deserialize(readFs,
789+
WuwaApiResponseContext.Default.WuwaLauncherDownloadConfig);
790+
if (existing != null)
791+
{
792+
// Carry over fields we don't want to overwrite.
793+
cfg.AppId = existing.AppId;
794+
cfg.ReUseVersion = existing.ReUseVersion ?? string.Empty;
795+
cfg.State = existing.State ?? string.Empty;
796+
cfg.IsPreDownload = false; // always clear the pre-download flag after a full update
797+
}
798+
}
799+
catch (Exception ex)
800+
{
801+
SharedStatic.InstanceLogger.LogWarning(
802+
"[WuwaGameManager::TryUpdateLauncherDownloadConfig] Could not read existing {File}: {Err}",
803+
fileName, ex.Message);
804+
}
805+
}
806+
807+
try
808+
{
809+
string tempPath = configPath + ".tmp";
810+
using (var writeFs = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.None))
811+
{
812+
JsonSerializer.Serialize(writeFs, cfg,
813+
WuwaApiResponseContext.Default.WuwaLauncherDownloadConfig);
814+
}
815+
File.Move(tempPath, configPath, overwrite: true);
816+
SharedStatic.InstanceLogger.LogInformation(
817+
"[WuwaGameManager::TryUpdateLauncherDownloadConfig] Updated {File} → version={Version}",
818+
fileName, version);
819+
}
820+
catch (Exception ex)
821+
{
822+
SharedStatic.InstanceLogger.LogWarning(
823+
"[WuwaGameManager::TryUpdateLauncherDownloadConfig] Failed to write {File}: {Err}",
824+
fileName, ex.Message);
825+
}
826+
}
827+
828+
/// <summary>
829+
/// Writes <c>LocalGameResources.json</c> to the game install directory using the
830+
/// supplied resource index. This mirrors the file that Kuro's official launcher
831+
/// maintains so the game and launcher remain in sync after installs/updates done
832+
/// through Collapse Launcher.
833+
/// </summary>
834+
internal void TryWriteLocalGameResources(string installPath, WuwaApiResponseResourceIndex index)
835+
{
836+
const string fileName = "LocalGameResources.json";
837+
string configPath = Path.Combine(installPath, fileName);
838+
839+
try
840+
{
841+
string tempPath = configPath + ".tmp";
842+
using (var writeFs = new FileStream(tempPath, FileMode.Create, FileAccess.Write, FileShare.None))
843+
{
844+
JsonSerializer.Serialize(writeFs, index,
845+
WuwaApiResponseContext.Default.WuwaApiResponseResourceIndex);
846+
}
847+
File.Move(tempPath, configPath, overwrite: true);
848+
SharedStatic.InstanceLogger.LogInformation(
849+
"[WuwaGameManager::TryWriteLocalGameResources] Wrote {File} ({Count} entries)",
850+
fileName, index.Resource.Length);
851+
}
852+
catch (Exception ex)
853+
{
854+
SharedStatic.InstanceLogger.LogWarning(
855+
"[WuwaGameManager::TryWriteLocalGameResources] Failed to write {File}: {Err}",
856+
fileName, ex.Message);
857+
}
858+
}
859+
761860
/// <summary>
762861
/// Finds a patch config entry that patches FROM the given version to the current API game version.
763862
/// </summary>

0 commit comments

Comments
 (0)