adds IReleaseFormat with a legacy-json-blob implementation lifting the existing per-file update behaviour, and an m2pack implementation that loads runtime-key.json after apply. a central ReleaseFormatFactory maps Manifest.EffectiveFormat onto concrete strategies and throws on unknown values so a signed but unsupported format cannot silently downgrade. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
53 lines
2.3 KiB
C#
53 lines
2.3 KiB
C#
using Metin2Launcher.Manifest;
|
|
|
|
namespace Metin2Launcher.Formats;
|
|
|
|
/// <summary>
|
|
/// Strategy that knows how to interpret the <c>files</c> array of a
|
|
/// signature-verified manifest. Added for the m2pack migration:
|
|
///
|
|
/// - <c>legacy-json-blob</c> ships individual files that replace their
|
|
/// counterparts inside the client root one-for-one.
|
|
/// - <c>m2pack</c> ships <c>.m2p</c> pack archives and a <c>runtime-key.json</c>
|
|
/// sidecar. The archives are placed next to the client root and the
|
|
/// runtime key is forwarded to the game process via env vars — the
|
|
/// launcher NEVER opens, decrypts or decompresses an <c>.m2p</c> archive.
|
|
///
|
|
/// Both implementations share the same download/apply plumbing in
|
|
/// <see cref="Orchestration.UpdateOrchestrator"/>. This interface only
|
|
/// captures the pieces that actually differ between the two formats.
|
|
/// </summary>
|
|
public interface IReleaseFormat
|
|
{
|
|
/// <summary>Identifier matching <see cref="Manifest.EffectiveFormat"/>.</summary>
|
|
string Name { get; }
|
|
|
|
/// <summary>
|
|
/// Filters the manifest file list down to entries that should be
|
|
/// downloaded on the given platform. Both formats currently delegate
|
|
/// to <see cref="ManifestFile.AppliesTo(string)"/>; the indirection
|
|
/// exists so a future format can special-case (e.g. exclude the
|
|
/// runtime key from platform filtering, or reject unknown kinds).
|
|
/// </summary>
|
|
IReadOnlyList<ManifestFile> FilterApplicable(Manifest.Manifest manifest, string platform);
|
|
|
|
/// <summary>
|
|
/// Runs after the apply phase succeeds. The legacy format is a no-op;
|
|
/// the m2pack format loads the runtime key from the client root and
|
|
/// stores it on <paramref name="outcome"/> so the caller can forward it
|
|
/// to the game process.
|
|
/// </summary>
|
|
void OnApplied(string clientRoot, LoadedManifest manifest, ReleaseOutcome outcome);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Mutable bag of results emitted by <see cref="IReleaseFormat.OnApplied"/>.
|
|
/// Kept separate from the update orchestrator's own <c>Result</c> record so
|
|
/// format-specific data doesn't leak into the generic update flow.
|
|
/// </summary>
|
|
public sealed class ReleaseOutcome
|
|
{
|
|
/// <summary>Populated by the m2pack format; null for legacy releases.</summary>
|
|
public Runtime.RuntimeKey? RuntimeKey { get; set; }
|
|
}
|