mirror of
https://github.com/WinDurango/WinDurango.UI.git
synced 2026-01-31 00:55:24 +01:00
(NOT FINISHED) rewrite InstalledPackages.cs + more
Co-Authored-By: danil <61111955+danilwhale@users.noreply.github.com>
This commit is contained in:
@@ -28,6 +28,7 @@ namespace WinDurango.UI
|
||||
public static readonly uint VerPacked = (Major << 22) | (Minor << 12) | Patch;
|
||||
public static readonly string Version = $"{Fvi.ProductMajorPart}.{Fvi.ProductMinorPart}.{Fvi.ProductBuildPart}_{Hash}"; // 1.0 will be when bugs are squashed and everything works correctly.
|
||||
// other
|
||||
public static readonly InstalledPackages InstalledPackages = new InstalledPackages();
|
||||
public static readonly WdSettings Settings = new();
|
||||
public static readonly MainWindow MainWindow = new();
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<Flyout Placement="Bottom">
|
||||
<StackPanel>
|
||||
<CheckBox Content="Unregister package" Name="unregisterCheckbox" IsChecked="True"/>
|
||||
<CheckBox Content="Unpatch package" Name="unpatchCheckbox" IsChecked="True"/>
|
||||
</StackPanel>
|
||||
</Flyout>
|
||||
</SplitButton.Flyout>
|
||||
|
||||
@@ -35,20 +35,23 @@ namespace WinDurango.UI.Controls
|
||||
{
|
||||
if ((bool)unregisterCheckbox.IsChecked)
|
||||
{
|
||||
var confirmation = new Confirmation(Localization.Locale.GetLocalizedText("Packages.UninstallConfirmation", _Name), "Uninstall?");
|
||||
var confirmation =
|
||||
new Confirmation(Localization.Locale.GetLocalizedText("Packages.UninstallConfirmation", _Name),
|
||||
"Uninstall?");
|
||||
Dialog.BtnClicked answer = await confirmation.Show();
|
||||
if (answer == Dialog.BtnClicked.Yes)
|
||||
{
|
||||
if (InstalledPackages.RemoveSymlinks(_familyName))
|
||||
await Packages.RemovePackage(_package);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (InstalledPackages.RemoveSymlinks(_familyName))
|
||||
InstalledPackages.RemoveInstalledPackage(_package);
|
||||
App.MainWindow.AppsListPage.InitAppList();
|
||||
|
||||
if (answer != Dialog.BtnClicked.Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bool)unpatchCheckbox.IsChecked && await WinDurangoPatcher.UnpatchPackage(_package, null))
|
||||
UnpatchPackage(_package, null);
|
||||
|
||||
if ((bool)unregisterCheckbox.IsChecked)
|
||||
await Packages.RemovePackage(_package);
|
||||
|
||||
App.InstalledPackages.RemovePackage(_package);
|
||||
App.MainWindow.AppsListPage.InitAppList();
|
||||
}
|
||||
|
||||
private void OpenFolder(object sender, RoutedEventArgs e)
|
||||
@@ -59,6 +62,8 @@ namespace WinDurango.UI.Controls
|
||||
|
||||
private async Task StatusUpdateAsync(string status, int progress)
|
||||
{
|
||||
Logger.WriteInformation(status);
|
||||
|
||||
if (currentDialog == null)
|
||||
{
|
||||
currentDialog = new ProgressDialog("Working", "Patcher", false);
|
||||
@@ -173,7 +178,11 @@ namespace WinDurango.UI.Controls
|
||||
|
||||
MenuFlyout rcFlyout = new();
|
||||
|
||||
bool isPatched = InstalledPackages.GetInstalledPackage(_package.Id.FamilyName).Value.installedPackage.IsPatched;
|
||||
bool isPatched = false;
|
||||
|
||||
installedPackage instPackage = App.InstalledPackages.GetPackage(_package.Id.FamilyName);
|
||||
if (instPackage != null)
|
||||
isPatched = instPackage.IsPatched;
|
||||
|
||||
MenuFlyoutItem patchButton = new MenuFlyoutItem
|
||||
{
|
||||
|
||||
@@ -110,8 +110,8 @@ namespace WinDurango.UI.Dialogs
|
||||
var package = listViewItem.Tag as Package;
|
||||
if (package != null && package?.Id?.FamilyName != null)
|
||||
{
|
||||
if (InstalledPackages.GetInstalledPackage(package.Id.FamilyName) == null)
|
||||
InstalledPackages.AddInstalledPackage(package);
|
||||
if (App.InstalledPackages.GetPackage(package.Id.FamilyName) == null)
|
||||
App.InstalledPackages.AddPackage(package);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
SecondaryButtonText="Cancel">
|
||||
<Grid>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Name="packageLogo" MaxHeight="128" MaxWidth="128"></Image>
|
||||
<Image x:Name="packageLogo" MaxHeight="128" MaxWidth="128"></Image>
|
||||
<StackPanel Margin="10 0 0 0" Orientation="Vertical">
|
||||
<TextBlock Name="packageName" FontWeight="Bold" FontSize="18" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock Name="packagePublisher" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock Name="packageVersion" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock Name="packageLocation" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock x:Name="packageName" FontWeight="Bold" FontSize="18" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock x:Name="packagePublisher" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock x:Name="packageVersion" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
<TextBlock x:Name="packageLocation" TextWrapping="Wrap" MaxWidth="400"></TextBlock>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Composition.SystemBackdrops;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
@@ -5,6 +6,7 @@ using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using WinDurango.UI.Dialogs;
|
||||
using WinDurango.UI.Pages;
|
||||
using WinDurango.UI.Settings;
|
||||
@@ -20,6 +22,34 @@ namespace WinDurango.UI
|
||||
public SettingsPage SettingsPage;
|
||||
public AboutPage AboutPage;
|
||||
|
||||
// ignore
|
||||
// public async Task StatusUpdateAsync(string status, string title, int progress)
|
||||
// {
|
||||
// if (currentDialog == null)
|
||||
// {
|
||||
// currentDialog = new ProgressDialog(status, title, false);
|
||||
// // shitty way of doing it
|
||||
// if (new ProgressDialog(status, title, false) != null)
|
||||
// {
|
||||
// await DispatcherQueue.EnqueueAsync(async () =>
|
||||
// {
|
||||
// await currentDialog.ShowAsync();
|
||||
// });
|
||||
// } else
|
||||
// {
|
||||
// Logger.WriteDebug("???");
|
||||
// }
|
||||
// } else
|
||||
// {
|
||||
// currentDialog.Text = status;
|
||||
// currentDialog.Progress = progress;
|
||||
// if (progress == 100)
|
||||
// {
|
||||
// currentDialog.Hide();
|
||||
// currentDialog = null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void NavigationInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||
{
|
||||
|
||||
@@ -26,8 +26,8 @@ namespace WinDurango.UI.Pages
|
||||
|
||||
windurango_Info.developerInfo.Text = $"Version {App.Version}";
|
||||
windurango_Info.developerName.Content = "WinDurango.UI";
|
||||
windurango_Info.developerName.NavigateUri = new Uri("https://github.com/WinDurango-project/WinDurango.UI");
|
||||
windurango_Info.developerPicture.ProfilePicture = new BitmapImage(new Uri(getGitHubPfp("WinDurango-project")));
|
||||
windurango_Info.developerName.NavigateUri = new Uri("https://github.com/WinDurango/WinDurango.UI");
|
||||
windurango_Info.developerPicture.ProfilePicture = new BitmapImage(new Uri(getGitHubPfp("WinDurango")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,22 +26,22 @@ namespace WinDurango.UI.Pages
|
||||
{
|
||||
appList.Children.Clear();
|
||||
|
||||
Dictionary<string, InstalledPackage> installedPackages = InstalledPackages.GetInstalledPackages();
|
||||
List<installedPackage> installedPackages = App.InstalledPackages.GetPackages();
|
||||
var pm = new PackageManager();
|
||||
|
||||
foreach (var installedPackage in installedPackages)
|
||||
{
|
||||
if (pm.FindPackageForUser(WindowsIdentity.GetCurrent().User?.Value, installedPackage.Value.FullName) != null)
|
||||
if (pm.FindPackageForUser(WindowsIdentity.GetCurrent().User?.Value, installedPackage.FullName) != null)
|
||||
{
|
||||
Grid outerGrid = new();
|
||||
AppTile gameContainer = new(installedPackage.Key);
|
||||
AppTile gameContainer = new(installedPackage.FamilyName);
|
||||
outerGrid.Children.Add(gameContainer);
|
||||
appList.Children.Add(outerGrid);
|
||||
Logger.WriteDebug($"Added {installedPackage.Key} to the app list");
|
||||
Logger.WriteDebug($"Added {installedPackage.FamilyName} to the app list");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteError($"Couldn't find package {installedPackage.Value.FullName} in installed UWP packages list");
|
||||
Logger.WriteError($"Couldn't find package {installedPackage.FullName} in installed UWP packages list");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,41 +8,56 @@ using WinDurango.UI.Utils;
|
||||
|
||||
namespace WinDurango.UI.Settings
|
||||
{
|
||||
public class InstalledPackage
|
||||
public class installedPackage
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
public List<string> SymlinkedDLLs { get; set; }
|
||||
public List<string> OriginalDLLs { get; set; }
|
||||
public string FamilyName { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string InstallPath { get; set; }
|
||||
public List<string> PatchedDlls { get; set; }
|
||||
public List<string> OriginalDlls { get; set; }
|
||||
public bool IsPatched { get; set; }
|
||||
}
|
||||
|
||||
// TODO: make this not static
|
||||
public abstract class InstalledPackages
|
||||
public class InstalledPackages
|
||||
{
|
||||
|
||||
public static void RemoveInstalledPackage(Package pkg)
|
||||
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
|
||||
{
|
||||
string path = App.DataDir;
|
||||
if (!Directory.Exists(path))
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
private readonly List<installedPackage> _installedPackages;
|
||||
|
||||
public InstalledPackages()
|
||||
{
|
||||
if (!Directory.Exists(App.DataDir))
|
||||
{
|
||||
_ = Directory.CreateDirectory(path);
|
||||
Directory.CreateDirectory(App.DataDir);
|
||||
}
|
||||
|
||||
string filePath = Path.Combine(path, "InstalledPackages.json");
|
||||
string filePath = Path.Combine(App.DataDir, "InstalledPackages.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Logger.WriteError("Could not get the list of installed packages!");
|
||||
using StreamWriter writer = File.CreateText(filePath);
|
||||
writer.WriteLine("{}");
|
||||
Logger.WriteInformation("Creating empty InstalledPackages.json");
|
||||
File.WriteAllText(filePath, "{}");
|
||||
_installedPackages = [];
|
||||
}
|
||||
|
||||
string json = File.ReadAllText(filePath);
|
||||
var installedPkgs = JsonSerializer.Deserialize<Dictionary<string, InstalledPackage>>(json) ?? [];
|
||||
|
||||
if (installedPkgs.TryGetValue(pkg.Id.FamilyName, out var package) && package.FullName == pkg.Id.FullName)
|
||||
else
|
||||
{
|
||||
_ = installedPkgs.Remove(pkg.Id.FamilyName);
|
||||
string json = File.ReadAllText(filePath);
|
||||
|
||||
_installedPackages = JsonSerializer.Deserialize<List<installedPackage>>(json)
|
||||
?? [];
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePackage(Package pkg)
|
||||
{
|
||||
installedPackage package = _installedPackages.Find(p => p.FamilyName == pkg.Id.FamilyName);
|
||||
if (package != null && package.FullName == pkg.Id.FullName)
|
||||
{
|
||||
_installedPackages.Remove(package);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -50,121 +65,67 @@ namespace WinDurango.UI.Settings
|
||||
return;
|
||||
}
|
||||
|
||||
string updated = JsonSerializer.Serialize(installedPkgs, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(filePath, updated);
|
||||
Save();
|
||||
Logger.WriteInformation($"Removed {pkg.DisplayName} ({pkg.Id.FamilyName}) from the InstalledPackages list.");
|
||||
}
|
||||
|
||||
|
||||
public static Dictionary<string, InstalledPackage> GetInstalledPackages()
|
||||
public List<installedPackage> GetPackages()
|
||||
{
|
||||
if (!Directory.Exists(App.DataDir))
|
||||
{
|
||||
_ = Directory.CreateDirectory(App.DataDir);
|
||||
}
|
||||
|
||||
string filePath = Path.Combine(App.DataDir, "InstalledPackages.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Logger.WriteError("Could not get the list of installed packages!");
|
||||
using StreamWriter writer = File.CreateText(filePath);
|
||||
writer.WriteLine("{}");
|
||||
}
|
||||
|
||||
string json = File.ReadAllText(filePath);
|
||||
|
||||
Dictionary<string, InstalledPackage> installedPkgs = JsonSerializer.Deserialize<Dictionary<string, InstalledPackage>>(json)
|
||||
?? [];
|
||||
|
||||
return installedPkgs;
|
||||
return _installedPackages;
|
||||
}
|
||||
|
||||
public static void SaveInstalledPackages(Dictionary<string, InstalledPackage> installedPkgs)
|
||||
public installedPackage? GetPackage(Package pkg)
|
||||
{
|
||||
string json = JsonSerializer.Serialize(installedPkgs, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(Path.Combine(App.DataDir, "InstalledPackages.json"), json);
|
||||
Logger.WriteDebug($"Saved InstalledPackages.json");
|
||||
return _installedPackages.Find(p => p.FamilyName == pkg.Id.FamilyName);
|
||||
}
|
||||
|
||||
public installedPackage? GetPackage(string familyName)
|
||||
{
|
||||
return _installedPackages.Find(p => p.FamilyName == familyName);
|
||||
}
|
||||
|
||||
public static void UpdateInstalledPackage(string familyName, InstalledPackage installedPkg)
|
||||
public void UpdatePackage(installedPackage package)
|
||||
{
|
||||
Dictionary<string, InstalledPackage> installedPkgs = GetInstalledPackages();
|
||||
|
||||
installedPkgs[familyName] = installedPkg;
|
||||
SaveInstalledPackages(installedPkgs);
|
||||
}
|
||||
|
||||
public static bool RemoveSymlinks(string familyName)
|
||||
{
|
||||
var pkg = GetInstalledPackage(familyName).Value;
|
||||
var pkgMount = Packages.GetPackageByFamilyName(pkg.familyName).EffectivePath;
|
||||
|
||||
if (Directory.Exists(pkgMount))
|
||||
int index = _installedPackages.FindIndex(p => p.FamilyName == package.FamilyName);
|
||||
if (index < 0)
|
||||
{
|
||||
foreach (var symlink in pkg.installedPackage.SymlinkedDLLs)
|
||||
{
|
||||
string symlinkPath = Path.Combine(pkgMount, symlink);
|
||||
if (File.Exists(symlinkPath))
|
||||
{
|
||||
var attributes = File.GetAttributes(symlinkPath);
|
||||
if (attributes.HasFlag(FileAttributes.ReparsePoint))
|
||||
{
|
||||
File.Delete(symlinkPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
_installedPackages.Add(package);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
_installedPackages[index] = package;
|
||||
}
|
||||
return true;
|
||||
Save();
|
||||
}
|
||||
|
||||
public static (string familyName, InstalledPackage installedPackage)? GetInstalledPackage(string familyName)
|
||||
public void Save()
|
||||
{
|
||||
Dictionary<string, InstalledPackage> installedPkgs = GetInstalledPackages();
|
||||
return installedPkgs.TryGetValue(familyName, out InstalledPackage installedPkg) ? (familyName, installedPkg) : null;
|
||||
string json = JsonSerializer.Serialize(_installedPackages, JsonSerializerOptions);
|
||||
File.WriteAllText(Path.Combine(App.DataDir, "InstalledPackages.json"), json);
|
||||
Logger.WriteDebug("Saved InstalledPackages.json");
|
||||
}
|
||||
|
||||
public static void AddInstalledPackage(Package package)
|
||||
|
||||
public void AddPackage(Package package)
|
||||
{
|
||||
string path = App.DataDir;
|
||||
if (!Directory.Exists(path))
|
||||
if (_installedPackages.Exists(p => p.FamilyName == package.Id.FamilyName))
|
||||
{
|
||||
_ = Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
string filePath = Path.Combine(path, "InstalledPackages.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
Logger.WriteError("Could not get the list of installed packages!");
|
||||
using StreamWriter writer = File.CreateText(filePath);
|
||||
writer.WriteLine("{}");
|
||||
}
|
||||
|
||||
string json = File.ReadAllText(filePath);
|
||||
var installedPkgs = JsonSerializer.Deserialize<Dictionary<string, InstalledPackage>>(json) ?? [];
|
||||
|
||||
if (installedPkgs.ContainsKey(package.Id.FamilyName))
|
||||
{
|
||||
Logger.WriteError($"Couldn't add {package.DisplayName} as it already exists in the InstalledPackages JSON.");
|
||||
Logger.WriteError($"Couldn't add {package.DisplayName} as it already exists.");
|
||||
return;
|
||||
}
|
||||
|
||||
installedPkgs[package.Id.FamilyName] = new InstalledPackage
|
||||
_installedPackages.Add(new installedPackage
|
||||
{
|
||||
FullName = package.Id.FullName,
|
||||
SymlinkedDLLs = [],
|
||||
OriginalDLLs = [],
|
||||
IsPatched = false
|
||||
};
|
||||
FamilyName = package.Id.FamilyName,
|
||||
Version =
|
||||
$"{package.Id.Version.Major}.{package.Id.Version.Minor}.{package.Id.Version.Build}.{package.Id.Version.Revision}",
|
||||
InstallPath = package.InstalledPath,
|
||||
PatchedDlls = [],
|
||||
OriginalDlls = [],
|
||||
IsPatched = Path.Exists(package.InstalledPath)
|
||||
});
|
||||
|
||||
string updated = JsonSerializer.Serialize(installedPkgs, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(filePath, updated);
|
||||
Logger.WriteInformation($"Added {package.DisplayName} ({package.Id.FamilyName}) to the InstalledPackages list.");
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ using static WinDurango.UI.Localization.Locale;
|
||||
|
||||
namespace WinDurango.UI.Utils
|
||||
{
|
||||
// do not touch or you will combust from all the glue holding this together
|
||||
// this class sucks so much that we literally had to stop bc we didn't know how to rewrite a function and make it still work with the UI stuff
|
||||
public abstract class Packages
|
||||
{
|
||||
// TODO: Make these methods not use the GUI, instead just throw an exception and catch it in the area where the method is actually invoked.
|
||||
@@ -71,27 +73,6 @@ namespace WinDurango.UI.Utils
|
||||
}
|
||||
|
||||
string package = await InstallPackageAsync(new Uri(mountDir + "\\AppxManifest.xml", UriKind.Absolute), addInstalledPackage);
|
||||
|
||||
if (package == null || !addInstalledPackage)
|
||||
return;
|
||||
|
||||
var (familyName, installedPackage) = InstalledPackages.GetInstalledPackage(package).Value;
|
||||
|
||||
// DO NOT COPY THE DLLS FROM THIS
|
||||
//if (hasExvd)
|
||||
//{
|
||||
// foreach (string filePath in Directory.GetFiles(Path.Combine(exvdDir + "\\Windows\\System32")))
|
||||
// {
|
||||
// string fileName = Path.GetFileName(filePath);
|
||||
|
||||
// if (File.Exists(Path.Combine(mountDir, fileName)))
|
||||
// continue;
|
||||
|
||||
// FileSystemInfo symlink = File.CreateSymbolicLink(Path.Combine(mountDir, fileName), filePath);
|
||||
// installedPackage.SymlinkedDLLs.Add(symlink.Name);
|
||||
// InstalledPackages.UpdateInstalledPackage(familyName, installedPackage);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public static string GetSplashScreenPath(Package pkg)
|
||||
@@ -201,7 +182,7 @@ namespace WinDurango.UI.Utils
|
||||
{
|
||||
status.Text = $"Ui.UpdatingAppList".GetLocalizedString();
|
||||
status.Progress = 80.0;
|
||||
InstalledPackages.AddInstalledPackage(recentPkg);
|
||||
App.InstalledPackages.AddPackage(recentPkg);
|
||||
status.Progress = 90.0;
|
||||
App.MainWindow.ReloadAppList();
|
||||
status.Progress = 100.0;
|
||||
@@ -238,7 +219,7 @@ namespace WinDurango.UI.Utils
|
||||
var undeployment = await pm.RemovePackageAsync(package.Id.FullName, RemovalOptions.PreserveApplicationData);
|
||||
|
||||
status.Progress = 50.0;
|
||||
InstalledPackages.RemoveInstalledPackage(package);
|
||||
App.InstalledPackages.RemovePackage(package);
|
||||
status.Progress = 100.0;
|
||||
status.Hide();
|
||||
Logger.WriteInformation($"{package.DisplayName} was uninstalled.");
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using WinDurango.UI.Settings;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using Package = Windows.ApplicationModel.Package;
|
||||
|
||||
namespace WinDurango.UI.Utils
|
||||
{
|
||||
@@ -23,62 +24,76 @@ namespace WinDurango.UI.Utils
|
||||
public string DownloadLink { get; set; }
|
||||
}
|
||||
|
||||
public class WinDurangoPatcher
|
||||
public static class WinDurangoPatcher
|
||||
{
|
||||
private static readonly HttpClient httpClient = new(new HttpClientHandler { AllowAutoRedirect = true });
|
||||
private static GitHubRelease wdRelease;
|
||||
private static string patchDir = Path.Combine(App.DataDir, "WinDurangoCore");
|
||||
private static string patchesPath = Path.Combine(App.DataDir, "WinDurangoCore");
|
||||
|
||||
public static async Task<bool> PatchPackage(Windows.ApplicationModel.Package package, bool forceRedownload, Func<string, int, Task> statusCallback)
|
||||
static WinDurangoPatcher()
|
||||
{
|
||||
Logger.WriteInformation($"Patching package {package.Id.FamilyName}");
|
||||
statusCallback($"Patching {package.Id.FamilyName}", 0);
|
||||
string curDate = DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
var instPkg = InstalledPackages.GetInstalledPackage(package.Id.FamilyName);
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (compatible; GitHubAPI/1.0)");
|
||||
}
|
||||
|
||||
string installPath = package.InstalledPath;
|
||||
|
||||
statusCallback($"Getting release", 10);
|
||||
await GetOrReuseRelease(); // don't use the return value since wdRelease is set regardless
|
||||
public static async Task<bool> UnpatchPackage(Package package, Func<string, int, Task> statusCallback)
|
||||
{
|
||||
installedPackage pkg = App.InstalledPackages.GetPackage(package);
|
||||
if (pkg == null)
|
||||
return false;
|
||||
|
||||
return await UnpatchPackage(pkg, statusCallback);
|
||||
}
|
||||
|
||||
public static async Task<bool> PatchPackage(Package package, bool forceRedownload,
|
||||
Func<string, int, Task> statusCallback)
|
||||
{
|
||||
installedPackage pkg = App.InstalledPackages.GetPackage(package);
|
||||
if (pkg == null)
|
||||
return false;
|
||||
|
||||
return await PatchPackage(pkg, forceRedownload, statusCallback);
|
||||
}
|
||||
|
||||
public static async Task<bool> PatchPackage(installedPackage package, bool forceRedownload,
|
||||
Func<string, int, Task> statusCallback)
|
||||
{
|
||||
statusCallback($"Patching {package.FamilyName}", 0);
|
||||
string curDate = DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
string installPath = package.InstallPath;
|
||||
|
||||
if (!Path.Exists(patchDir) || forceRedownload)
|
||||
statusCallback("Getting latest release", 10);
|
||||
await GetOrReuseRelease(); // don't use the return value since wdRelease is set regardless
|
||||
|
||||
if (!Path.Exists(patchesPath) || forceRedownload)
|
||||
{
|
||||
if (forceRedownload && Path.Exists(patchDir))
|
||||
Directory.Delete(patchDir, true);
|
||||
if (Path.Exists(patchesPath))
|
||||
Directory.Delete(patchesPath, true);
|
||||
|
||||
string zip = Path.Combine(App.DataDir, "WinDurangoCore.zip");
|
||||
string archivePath = Path.Combine(App.DataDir, "WinDurangoCore.zip");
|
||||
|
||||
try
|
||||
{
|
||||
using (HttpClient client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true }))
|
||||
{
|
||||
statusCallback($"Downloading WinDurango release \"{wdRelease.Name}\"", 20);
|
||||
Logger.WriteInformation($"Downloading WinDurango release \"{wdRelease.Name}\"");
|
||||
using (HttpResponseMessage res = await client.GetAsync(wdRelease.DownloadLink, HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
res.EnsureSuccessStatusCode();
|
||||
statusCallback($"Downloading release \"{wdRelease.Name}\"", 20);
|
||||
|
||||
using (FileStream stream = new FileStream(zip, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
statusCallback($"Writing release zip", 30);
|
||||
await res.Content.CopyToAsync(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
// using HttpResponseMessage res = await httpClient.GetAsync(wdRelease.DownloadLink,
|
||||
// HttpCompletionOption.ResponseHeadersRead);
|
||||
// res.EnsureSuccessStatusCode();
|
||||
await using Stream httpStream = await httpClient.GetStreamAsync(wdRelease.DownloadLink);
|
||||
await using FileStream stream = new(archivePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
statusCallback("Writing release zip", 30);
|
||||
await httpStream.CopyToAsync(stream);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(patchDir);
|
||||
Logger.WriteInformation($"Unzipping");
|
||||
statusCallback($"Unzipping", 40);
|
||||
ZipFile.ExtractToDirectory(zip, patchDir);
|
||||
Directory.CreateDirectory(patchesPath);
|
||||
statusCallback($"Extracting", 40);
|
||||
ZipFile.ExtractToDirectory(archivePath, patchesPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -87,81 +102,93 @@ namespace WinDurango.UI.Utils
|
||||
}
|
||||
}
|
||||
|
||||
statusCallback($"Patching", 50);
|
||||
if (Path.Exists(patchDir))
|
||||
statusCallback("Patching", 50);
|
||||
if (Path.Exists(patchesPath))
|
||||
{
|
||||
DirectoryInfo unzipped = new DirectoryInfo(patchDir);
|
||||
DirectoryInfo patchesDir = new(patchesPath);
|
||||
|
||||
var unzippedFiles = unzipped.GetFiles("*.dll");
|
||||
float prog = (90 - 50) / (float)unzippedFiles.Length;
|
||||
DirectoryInfo pkg = new DirectoryInfo(installPath);
|
||||
FileInfo[] patchFiles = patchesDir.GetFiles("*.dll");
|
||||
float progressPerFile = (90 - 50) / (float)patchFiles.Length;
|
||||
DirectoryInfo packageDir = new(installPath);
|
||||
|
||||
foreach (var file in unzippedFiles)
|
||||
foreach (FileInfo file in patchFiles)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + prog * Array.IndexOf(unzippedFiles, file));
|
||||
int progress = (int)Math.Round(50 + progressPerFile * Array.IndexOf(patchFiles, file));
|
||||
|
||||
statusCallback($"Copying {file.Name}", progress);
|
||||
var pkgFName = pkg.GetFiles("*.dll").FirstOrDefault(pkgFName => pkgFName.Name == file.Name);
|
||||
if (pkgFName != null)
|
||||
FileInfo oldFile = packageDir.GetFiles("*.dll").FirstOrDefault(f => f.Name == file.Name);
|
||||
if (oldFile != null)
|
||||
{
|
||||
Logger.WriteInformation($"Backing up old {pkgFName.Name}");
|
||||
Logger.WriteInformation($"Backing up old {oldFile.Name}");
|
||||
string DllBackup = Path.Combine(installPath, "WDDllBackup", curDate);
|
||||
if (!Path.Exists(DllBackup))
|
||||
Directory.CreateDirectory(DllBackup);
|
||||
|
||||
File.Move(pkgFName.FullName, Path.Combine(DllBackup, pkgFName.Name));
|
||||
if (!instPkg.Value.installedPackage.OriginalDLLs.Contains(Path.Combine(DllBackup, pkgFName.Name)))
|
||||
instPkg.Value.installedPackage.OriginalDLLs.Add(Path.Combine(DllBackup, pkgFName.Name));
|
||||
File.Move(oldFile.FullName, Path.Combine(DllBackup, oldFile.Name));
|
||||
if (!package.OriginalDlls.Contains(Path.Combine(DllBackup, oldFile.Name)))
|
||||
package.OriginalDlls.Add(Path.Combine(DllBackup, oldFile.Name));
|
||||
}
|
||||
|
||||
string symPath = Path.Combine(installPath, file.Name);
|
||||
string patchPath = Path.Combine(installPath, file.Name);
|
||||
Logger.WriteInformation($"Added {file.Name}");
|
||||
File.Copy(file.FullName, Path.Combine(installPath, file.Name));
|
||||
if (!instPkg.Value.installedPackage.SymlinkedDLLs.Contains(symPath))
|
||||
instPkg.Value.installedPackage.SymlinkedDLLs.Add(symPath);
|
||||
|
||||
if (!package.PatchedDlls.Contains(patchPath))
|
||||
package.PatchedDlls.Add(patchPath);
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteError("How did this happen???? patchDir should exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
statusCallback($"Writing patch txt", 93);
|
||||
StringBuilder builder = new();
|
||||
builder.AppendLine($"# This file was patched by WinDurango.UI with WinDurango release \"{wdRelease.Name}\".");
|
||||
builder.AppendLine("# If you want to unpatch manually, delete this file and edit %appdata%\\WinDurango\\UI\\InstalledPackages.json and set IsPatched to false.");
|
||||
builder.AppendLine("# Format is ReleaseName;VerPacked");
|
||||
builder.AppendLine($"{wdRelease.Name.Replace(";","-")};{App.VerPacked}");
|
||||
await File.WriteAllTextAsync(Path.Combine(installPath, "installed.txt"), builder.ToString());
|
||||
|
||||
statusCallback($"Updating package list", 95);
|
||||
instPkg.Value.installedPackage.IsPatched = true;
|
||||
InstalledPackages.UpdateInstalledPackage(instPkg.Value.familyName, instPkg.Value.installedPackage);
|
||||
package.IsPatched = true;
|
||||
App.InstalledPackages.UpdatePackage(package);
|
||||
statusCallback($"Done!", 100);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<bool> UnpatchPackage(Windows.ApplicationModel.Package package, Func<string, int, Task> statusCallback)
|
||||
public static async Task<bool> UnpatchPackage(installedPackage package,
|
||||
Func<string, int, Task> statusCallback)
|
||||
{
|
||||
Logger.WriteInformation($"Unpatching package {package.Id.FamilyName}");
|
||||
statusCallback($"Unpatching {package.Id.FamilyName}", 0);
|
||||
var instPkg = InstalledPackages.GetInstalledPackage(package.Id.FamilyName);
|
||||
var dlls = instPkg.Value.installedPackage.SymlinkedDLLs.ToArray();
|
||||
var origDlls = instPkg.Value.installedPackage.OriginalDLLs.ToArray();
|
||||
statusCallback($"Unpatching {package.FamilyName}", 0);
|
||||
|
||||
string installPath = package.InstalledPath;
|
||||
string[] dlls = package.PatchedDlls.ToArray();
|
||||
string[] originalDlls = package.OriginalDlls.ToArray();
|
||||
|
||||
float delProg = (0 - 50) / (float)instPkg.Value.installedPackage.SymlinkedDLLs.Count;
|
||||
foreach (var dll in dlls)
|
||||
string installPath = package.InstallPath;
|
||||
|
||||
float progressPerRemove = (0 - 50) / (float)package.PatchedDlls.Count;
|
||||
foreach (string dll in dlls)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + delProg * Array.IndexOf(instPkg.Value.installedPackage.SymlinkedDLLs.ToArray(), dll));
|
||||
int progress = (int)Math.Round(50 + progressPerRemove * Array.IndexOf(package.PatchedDlls.ToArray(), dll));
|
||||
statusCallback($"Removing {dll}", progress);
|
||||
try
|
||||
{
|
||||
File.Delete(dll);
|
||||
} catch
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.WriteError($"Failed to delete {dll}.");
|
||||
}
|
||||
if (instPkg.Value.installedPackage.SymlinkedDLLs.Contains(dll))
|
||||
instPkg.Value.installedPackage.SymlinkedDLLs.Remove(dll);
|
||||
|
||||
package.PatchedDlls.Remove(dll);
|
||||
};
|
||||
|
||||
float repProg = (99 - 50) / (float)instPkg.Value.installedPackage.OriginalDLLs.Count;
|
||||
foreach (var dll in origDlls)
|
||||
float progressPerRevert = (98 - 50) / (float)package.OriginalDlls.Count;
|
||||
foreach (string dll in originalDlls)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + delProg * Array.IndexOf(origDlls, dll));
|
||||
int progress = (int)Math.Round(50 + progressPerRevert * Array.IndexOf(originalDlls, dll));
|
||||
statusCallback($"Placing back original DLL \"{dll}\"", progress);
|
||||
try
|
||||
{
|
||||
@@ -171,42 +198,44 @@ namespace WinDurango.UI.Utils
|
||||
{
|
||||
Logger.WriteError($"Failed to copy {dll}.");
|
||||
}
|
||||
if (instPkg.Value.installedPackage.OriginalDLLs.Contains(dll))
|
||||
instPkg.Value.installedPackage.OriginalDLLs.Remove(dll);
|
||||
|
||||
package.OriginalDlls.Remove(dll);
|
||||
};
|
||||
|
||||
instPkg.Value.installedPackage.IsPatched = false;
|
||||
package.IsPatched = false;
|
||||
|
||||
statusCallback($"Removing patched.txt", 99);
|
||||
if (Path.Exists(Path.Combine(installPath, "installed.txt")))
|
||||
File.Delete(Path.Combine(installPath, "installed.txt"));
|
||||
|
||||
statusCallback($"Updating package list", 99);
|
||||
InstalledPackages.UpdateInstalledPackage(instPkg.Value.familyName, instPkg.Value.installedPackage);
|
||||
App.InstalledPackages.UpdatePackage(package);
|
||||
statusCallback($"Done!", 100);
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't wanna use all the api shits lol
|
||||
public static async Task<GitHubRelease> GetOrReuseRelease()
|
||||
private static async Task<GitHubRelease> GetOrReuseRelease()
|
||||
{
|
||||
if (wdRelease.GetType() != typeof(GitHubRelease))
|
||||
if (wdRelease is null)
|
||||
await GetLatestRelease();
|
||||
|
||||
return wdRelease;
|
||||
}
|
||||
|
||||
public static async Task<GitHubRelease> GetLatestRelease()
|
||||
private static async Task<GitHubRelease> GetLatestRelease()
|
||||
{
|
||||
GitHubRelease release = new GitHubRelease();
|
||||
GitHubRelease release = new();
|
||||
|
||||
string url = $"https://api.github.com/repos/WinDurango/WinDurango/releases";
|
||||
const string url = $"https://api.github.com/repos/WinDurango/WinDurango/releases";
|
||||
|
||||
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (compatible; GitHubAPI/1.0)");
|
||||
var response = await client.GetAsync(url);
|
||||
HttpResponseMessage response = await httpClient.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
string json = await response.Content.ReadAsStringAsync();
|
||||
|
||||
JsonDocument document = JsonDocument.Parse(json);
|
||||
var releases = document.RootElement.EnumerateArray();
|
||||
JsonElement.ArrayEnumerator releases = document.RootElement.EnumerateArray();
|
||||
|
||||
if (!releases.MoveNext())
|
||||
throw new Exception("Couldn't find any releases?????");
|
||||
@@ -217,7 +246,7 @@ namespace WinDurango.UI.Utils
|
||||
|
||||
release.Name = name;
|
||||
|
||||
var assets = newestRelease.GetProperty("assets").EnumerateArray();
|
||||
JsonElement.ArrayEnumerator assets = newestRelease.GetProperty("assets").EnumerateArray();
|
||||
|
||||
if (!assets.MoveNext())
|
||||
throw new Exception("Couldn't find any assets?????");
|
||||
@@ -230,4 +259,4 @@ namespace WinDurango.UI.Utils
|
||||
return release;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,9 @@
|
||||
<DisableXbfLineInfo>False</DisableXbfLineInfo>
|
||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<Version>0.0.4</Version>
|
||||
<AssemblyVersion>$(Version)</AssemblyVersion>
|
||||
<Version>0.1.0</Version>
|
||||
<AssemblyVersion>0.1.0</AssemblyVersion>
|
||||
<Product>WinDurango UI</Product>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -42,6 +43,10 @@
|
||||
<PropertyGroup>
|
||||
<WindowsSdkPackageVersion>10.0.26100.38</WindowsSdkPackageVersion>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<AssemblyName>WinDurango UI</AssemblyName>
|
||||
<Authors>WinDurango</Authors>
|
||||
<Company>WinDurango</Company>
|
||||
<PackageProjectUrl>https://github.com/WinDurango/WinDurango.UI</PackageProjectUrl>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
|
||||
Reference in New Issue
Block a user