Files
launcher-next/Launcher.Next.Application/LegacyCompatibilityOverlayParser.cs
T

30 lines
2.4 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
namespace Launcher.Next.Application;
public static class LegacyCompatibilityOverlayParser
{
private sealed record Package(string Id,string Product,int ProductYear,string Architecture,string Channel,string Version);
private sealed record Entry(string MappingId,string Pattern,string LegacyPluginId,string? LegacyCatalog,string? LegacyInstall,Package Package);
private sealed record Document(int SchemaVersion,IReadOnlyList<Entry> Mappings);
private static readonly JsonSerializerOptions Options=new(){PropertyNameCaseInsensitive=true,UnmappedMemberHandling=JsonUnmappedMemberHandling.Disallow};
public static LegacyCompatibilityOverlay Parse(string json)
{
try
{
var document=JsonSerializer.Deserialize<Document>(json,Options)??throw new InvalidOperationException("LEGACY_OVERLAY_MALFORMED");
if(document.SchemaVersion!=1) throw new InvalidOperationException("LEGACY_MAPPING_SCHEMA_UNSUPPORTED");
if(document.Mappings.Count==0||document.Mappings.GroupBy(x=>x.MappingId,StringComparer.OrdinalIgnoreCase).Any(x=>x.Count()>1)) throw new InvalidOperationException("LEGACY_MAPPING_DUPLICATE");
var entries=document.Mappings.Select(x=>{
if(string.IsNullOrWhiteSpace(x.MappingId)||string.IsNullOrWhiteSpace(x.LegacyPluginId)||string.IsNullOrWhiteSpace(x.Package.Id)||x.Package.Version is "latest"||x.Package.Version.Contains('*')||x.Package.Version.Contains('>')||x.Package.Version.Contains('<')||!System.Text.RegularExpressions.Regex.IsMatch(x.Package.Version,@"^\d+\.\d+\.\d+(\.\d+)?$")) throw new InvalidOperationException("LEGACY_OVERLAY_MALFORMED");
if(!string.Equals(x.Package.Product,"Plant3D",StringComparison.Ordinal)||x.Package.ProductYear!=2026||!string.Equals(x.Package.Architecture,"x64",StringComparison.OrdinalIgnoreCase)||!new[]{"pilot","stable","development"}.Contains(x.Package.Channel,StringComparer.OrdinalIgnoreCase)) throw new InvalidOperationException("LEGACY_MAPPING_INCOMPATIBLE");
return new LegacyCompatibilityMapping(x.LegacyPluginId,x.Package.Id,x.Package.Version,x.Package.Channel);
}).ToArray();
var first=document.Mappings[0].Package;
return new("legacy-overlay-v1",first.Product,first.ProductYear,first.Architecture,false,entries);
}
catch(JsonException){throw new InvalidOperationException("LEGACY_OVERLAY_MALFORMED");}
}
}