using Mlaumcherb.Client.Avalonia.зримое; using Mlaumcherb.Client.Avalonia.сеть; using Mlaumcherb.Client.Avalonia.холопы; using Newtonsoft.Json.Linq; namespace Mlaumcherb.Client.Avalonia.классы; public class InstalledGameVersionProps : IComparable, IEquatable { [JsonRequired] public string Id { get; } public GameVersionCatalogProps? CatalogProps { get; set; } public RemoteVersionDescriptorProps? DescriptorProps { get; set; } private bool _isInstalled; [JsonIgnore] public bool IsInstalled { get => _isInstalled; set { _isInstalled = value; StatusChanged?.Invoke(value); } } [JsonIgnore] public IOPath DescriptorPath { get; } public event Action? StatusChanged; public InstalledGameVersionProps(string id, GameVersionCatalogProps? catalogProps, RemoteVersionDescriptorProps? descriptorProps) { this.Id = id; this.CatalogProps = catalogProps; this.DescriptorProps = descriptorProps; DescriptorPath = PathHelper.GetVersionDescriptorPath(id); IsInstalled = File.Exists(PathHelper.GetVersionJarFilePath(id)); } public async Task LoadDescriptor(bool checkForUpdates) { // check if DescriptorProps had been changed on on remote version catalog server if (checkForUpdates && CatalogProps is not null && DescriptorProps is not null) { var remoteCatalog = await NetworkHelper.DownloadStringAndDeserialize(CatalogProps.url); DescriptorProps = remoteCatalog.versions.Find(remoteProps => remoteProps.id == Id); if(DescriptorProps is null) LauncherApp.Logger.LogWarn(nameof(InstalledGameVersionProps), $"Game version '{Id}' was deleted from remote catalog '{CatalogProps.name}'." + "It is kept locally, but can't be updated anymore."); } // Descriptor is downloaded here if (!HashHelper.CheckFileSHA1(DescriptorPath, DescriptorProps?.sha1, checkForUpdates)) { if (DescriptorProps is null) throw new NullReferenceException( $"can't download game version descriptor '{Id}', because RemoteDescriptor is null"); // download descriptor await NetworkHelper.DownloadFile(DescriptorProps.url, DescriptorPath); } string descriptorText = File.ReadAllText(DescriptorPath); JObject descriptorRaw = JObject.Parse(descriptorText); // Descriptors can inherit from other descriptors. // For example, timerix-anarx-2 inherits from 1.12.2-forge-14.23.5.2860, which inherits from 1.12.2 while (descriptorRaw.TryGetValue("inheritsFrom", out var v)) { string parentDescriptorId = v.Value() ?? throw new Exception("inheritsFrom is null"); LauncherApp.Logger.LogInfo(Id, $"merging descriptor '{parentDescriptorId}' with '{Id}'"); IOPath parentDescriptorPath = PathHelper.GetVersionDescriptorPath(parentDescriptorId); if (!File.Exists(parentDescriptorPath)) throw new Exception($"Версия '{Id} требует установить версию '{parentDescriptorId}'"); JObject parentDescriptorRaw = JObject.Parse(File.ReadAllText(parentDescriptorPath)); // Remove `inheritsFrom: parentDescriptor.Id` to prevent overriding of `parentDescriptor.inheritsFrom` descriptorRaw.Remove("inheritsFrom"); // Merge child descriptor into its parent. // Child descriptor values override values of parent. // Array values are merged together. parentDescriptorRaw.Merge(descriptorRaw, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Concat }); descriptorRaw = parentDescriptorRaw; } var descriptor = descriptorRaw.ToObject() ?? throw new Exception($"can't parse descriptor file '{DescriptorPath}'"); return new GameVersion(this, descriptor); } public void Delete() { if(!IsInstalled) return; LauncherApp.Logger.LogInfo(Id, "Deleting files..."); var verdir = PathHelper.GetVersionDir(Id); if(Directory.Exists(verdir)) Directory.Delete(verdir); LauncherApp.Logger.LogInfo(Id, "Files deleted"); IsInstalled = false; } public override string ToString() => Id; public override int GetHashCode() => Id.GetHashCode(); public int CompareTo(InstalledGameVersionProps? other) { if (ReferenceEquals(this, other)) return 0; if (other is null) return 1; return String.Compare(Id, other.Id, StringComparison.InvariantCulture); } public bool Equals(InstalledGameVersionProps? other) { if (other is null) return false; if (ReferenceEquals(this, other)) return true; return Id == other.Id; } public override bool Equals(object? obj) { if (obj is InstalledGameVersionProps other) return Equals(other); if (ReferenceEquals(this, obj)) return true; return false; } }