diff --git a/SA-Mod-Manager/App.xaml.cs b/SA-Mod-Manager/App.xaml.cs index c7b03387..ca6bd99d 100644 --- a/SA-Mod-Manager/App.xaml.cs +++ b/SA-Mod-Manager/App.xaml.cs @@ -625,25 +625,23 @@ public static Uri GetResourceUri(string resourceName) string fullResourceName = assembly.GetName().Name + ".Resources." + resourceName; // Load the resource stream from the assembly - using (Stream stream = assembly.GetManifestResourceStream(fullResourceName)) + using Stream stream = assembly.GetManifestResourceStream(fullResourceName); + // Check if the resource stream is found + if (stream == null) { - // Check if the resource stream is found - if (stream == null) - { - Console.WriteLine($"Resource not found: {fullResourceName}"); - return null; - } - - // Copy the resource stream to a temporary file - string tempFilePath = Path.GetTempFileName(); - using (FileStream fileStream = File.Create(tempFilePath)) - { - stream.CopyTo(fileStream); - } + Console.WriteLine($"Resource not found: {fullResourceName}"); + return null; + } - // Return the URI to the temporary file - return new Uri($"file://{tempFilePath}"); + // Copy the resource stream to a temporary file + string tempFilePath = Path.GetTempFileName(); + using (FileStream fileStream = File.Create(tempFilePath)) + { + stream.CopyTo(fileStream); } + + // Return the URI to the temporary file + return new Uri($"file://{tempFilePath}"); } private static ManagerSettings LoadManagerConfig() diff --git a/SA-Mod-Manager/GamesInstall.cs b/SA-Mod-Manager/GamesInstall.cs index ff2112f8..66d6f51b 100644 --- a/SA-Mod-Manager/GamesInstall.cs +++ b/SA-Mod-Manager/GamesInstall.cs @@ -8,6 +8,8 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using SAModManager.UI; +using Newtonsoft.Json; +using System.Net.Http; namespace SAModManager { @@ -105,7 +107,6 @@ public class Loader public static class GamesInstall { - public static async Task InstallDLL_Loader(Game game, bool isupdate = false) { if (game is null || !File.Exists(Path.Combine(game?.gameDirectory, game?.exeName))) @@ -118,45 +119,60 @@ public static async Task InstallDLL_Loader(Game game, bool isupdate = false) try { - Uri uri = new(game.loader.URL + "\r\n"); - var loader = new List - { - new DownloadInfo(game.loader.name, Path.GetFileName(game.loader.URL), game.modDirectory, uri, DownloadDialog.DLType.Install) - }; + string url_releases = App.CurrentGame.loader.URL; + string text_releases = string.Empty; + string assetName = App.CurrentGame.loader.name + ".7z"; + string mlverfile = App.CurrentGame.loader.mlverPath; + string currentTagName = File.Exists(mlverfile) ? File.ReadAllText(mlverfile) : App.CurrentGame.loader.defaultReleaseID; - var dl = new DownloadDialog(loader); - dl.StartDL(); + if (!uint.TryParse(currentTagName, out uint currentID)) + currentID = uint.Parse(App.CurrentGame.loader.defaultReleaseID); - if (dl.errorCount > 0 && !isupdate) + var httpClient = UpdateHelper.HttpClient; + string apiUrl = App.CurrentGame.loader.URL; + + HttpResponseMessage response = await httpClient.GetAsync(apiUrl); + + if (response.IsSuccessStatusCode) { - if (!File.Exists(loaderPath)) - { - var offline = new OfflineInstall(game.loader.name); - offline.Show(); - await Task.Delay(1000); - bool success = Util.ExtractEmbeddedDLL(game.loader.data, game.loader.name, game.modDirectory); - offline.CheckSuccess(success); - File.WriteAllText(App.CurrentGame.loader.mlverPath, "offlineVersionInstalled"); - await Task.Delay(500); - offline.Close(); - } - else + string responseBody = await response.Content.ReadAsStringAsync(); + var release = JsonConvert.DeserializeObject(responseBody); + if (release != null && release.Assets != null) { - dl.DisplayDownloadFailedMSG(null, game.loader.name); + var targetAsset = release.Assets.FirstOrDefault(asset => asset.Name.Equals(assetName, StringComparison.OrdinalIgnoreCase)); + if (targetAsset != null) + { + + if (uint.TryParse(release.TagName, out uint releaseID)) + { + if (releaseID > currentID) + { + await UpdateLoader(game, targetAsset.DownloadUrl, isupdate); + return; + } + } + + + } } } - else + + + //offline version + if (!File.Exists(loaderPath)) { - var lastCommit = await GitHub.GetLoaderHashCommit(); - if (lastCommit is not null) - { - File.WriteAllText(App.CurrentGame.loader.mlverPath, lastCommit); - } - else - { - File.WriteAllText(App.CurrentGame.loader.mlverPath, "loaderInstalledNoCommitIDFound"); - } + var offline = new OfflineInstall(game.loader.name); + offline.Show(); + await Task.Delay(700); + Util.ExtractEmbedded7z(game.loader.name + ".7z", game.modDirectory); + bool success = File.Exists(Path.Combine(game.modDirectory, game.loader.name + ".dll")); + offline.CheckSuccess(success); + + await Task.Delay(500); + offline.Close(); } + + } catch (Exception ex) { @@ -182,7 +198,7 @@ public static async Task InstallDLL_Loader(Game game, bool isupdate = false) } } - public static async Task UpdateLoader(Game game, string dlLink) + public static async Task UpdateLoader(Game game, string dlLink, bool update = true) { if (game is null) return false; @@ -194,7 +210,7 @@ public static async Task UpdateLoader(Game game, string dlLink) string pathFinal = Path.Combine(game.modDirectory, fileName); var loaderInfo = new List { - new DownloadInfo(game.loader.name, fileName, game.modDirectory, uri, DownloadDialog.DLType.Update) + new(game.loader.name, fileName, game.modDirectory, uri, update ? DownloadDialog.DLType.Update : DownloadDialog.DLType.Install) }; var dl = new DownloadDialog(loaderInfo); @@ -209,14 +225,14 @@ public static async Task UpdateLoader(Game game, string dlLink) dl.DownloadCompleted += () => { - if (File.Exists(App.CurrentGame.loader.dataDllOriginPath)) + if (File.Exists(pathFinal)) { bool retry = false; do { try { - + success = true; retry = false; } @@ -237,7 +253,11 @@ public static async Task UpdateLoader(Game game, string dlLink) List excludeFile = ["extlib"]; await Util.ExtractWExcludeFile(pathFinal, game.modDirectory, excludeFile); await Util.ExtractSpecificFile(pathFinal, "extlib", App.ConfigFolder); - File.Copy(App.CurrentGame.loader.loaderdllpath, App.CurrentGame.loader.dataDllPath, true); + if (update) + File.Copy(App.CurrentGame.loader.loaderdllpath, App.CurrentGame.loader.dataDllPath, true); + + if (File.Exists(pathFinal)) + File.Delete(pathFinal); } return success; } @@ -249,17 +269,6 @@ public static async Task UpdateLoader(Game game, string dlLink) return false; } - private static async Task PerformOfflineInstall(Dependencies dependency) - { - var offline = new OfflineInstall(dependency.name); - offline.Show(); - await Task.Delay(250); - offline.CheckSuccess(true); - await Task.Delay(250); - offline.Close(); - return true; - } - public static Game Unknown = new(); diff --git a/SA-Mod-Manager/SAModManager.csproj b/SA-Mod-Manager/SAModManager.csproj index 6af13752..b8ddc843 100644 --- a/SA-Mod-Manager/SAModManager.csproj +++ b/SA-Mod-Manager/SAModManager.csproj @@ -13,6 +13,7 @@ https://github.com/X-Hax/SA-Mod-Manager AnyCPU 1.3.0.2 + moderate @@ -46,6 +47,8 @@ + + @@ -59,6 +62,8 @@ + + diff --git a/SA-Mod-Manager/UI/MainWindow.xaml.cs b/SA-Mod-Manager/UI/MainWindow.xaml.cs index e8fafa9e..b9d4e4f9 100644 --- a/SA-Mod-Manager/UI/MainWindow.xaml.cs +++ b/SA-Mod-Manager/UI/MainWindow.xaml.cs @@ -2625,13 +2625,15 @@ private async Task InstallLoader() UpdateManagerStatusText(Lang.GetString("UpdateStatus.InstallLoader")); UIHelper.DisableButton(ref SaveAndPlayButton); - await GamesInstall.InstallDLL_Loader(App.CurrentGame); //first, we download and extract the loader DLL in the mods folder + await GamesInstall.InstallDLL_Loader(App.CurrentGame, false); //first, we download and extract the loader DLL in the mods folder UpdateManagerStatusText(Lang.GetString("UpdateStatus.InstallLoader")); //now we can move the loader files to the accurate folders. await Util.MoveFileAsync(App.CurrentGame.loader.dataDllPath, App.CurrentGame.loader.dataDllOriginPath, false); await Util.CopyFileAsync(App.CurrentGame.loader.loaderdllpath, App.CurrentGame.loader.dataDllPath, false); await App.EnableOneClickInstall(); + UpdateBtnInstallLoader_State(); + UIHelper.EnableButton(ref btnInstallLoader); UIHelper.EnableButton(ref SaveAndPlayButton); UpdateManagerStatusText(Lang.GetString("UpdateStatus.LoaderInstalled")); @@ -2657,7 +2659,7 @@ private async Task ForceInstallLoader() } else //install normally { - await GamesInstall.InstallDLL_Loader(App.CurrentGame); + await GamesInstall.InstallDLL_Loader(App.CurrentGame, false); UpdateManagerStatusText(Lang.GetString("UpdateStatus.InstallLoader")); //now we can move the loader files to the accurate folders. await Util.MoveFileAsync(App.CurrentGame.loader.dataDllPath, App.CurrentGame.loader.dataDllOriginPath, false); diff --git a/SA-Mod-Manager/Util.cs b/SA-Mod-Manager/Util.cs index cc1c0be0..3f8dfc7c 100644 --- a/SA-Mod-Manager/Util.cs +++ b/SA-Mod-Manager/Util.cs @@ -17,6 +17,7 @@ using SharpCompress.Archives; using SharpCompress.Common; using SharpCompress.Readers; +using SharpCompress.Archives.SevenZip; namespace SAModManager { @@ -204,31 +205,7 @@ public static async Task MoveFile(string origin, string dest, bool overwrite = f } } - public static bool ExtractEmbeddedDLL(byte[] resource, string resourceName, string outputDirectory) - { - string outputFilePath = null; - try - { - Util.CreateSafeDirectory(outputDirectory); - outputFilePath = Path.Combine(outputDirectory, resourceName + ".dll"); - - // Get the resource stream from Properties.Resources - using Stream resourceStream = new MemoryStream(resource); - using (FileStream fileStream = new(outputFilePath, FileMode.Create, FileAccess.Write)) - { - // Asynchronously copy the stream to the output file - resourceStream.CopyTo(fileStream); - } - } - catch (Exception ex) - { - Console.WriteLine($"Exception during DLL extraction: {ex}"); - return false; - } - FileInfo fileInfo = new(outputFilePath); - return fileInfo is not null && fileInfo.Length > 0; - } private static string FindExePath(string exeName) @@ -452,6 +429,25 @@ public static async Task ExtractSpecificFile(string zipPath, string specificFile await Task.Delay(150); } + public static void ExtractEmbedded7z(string resourceName, string outputDirectory) + { + + Assembly assembly = Assembly.GetExecutingAssembly(); + string fullResourceName = assembly.GetName().Name + ".Resources." + resourceName; + using Stream resourceStream = assembly.GetManifestResourceStream(fullResourceName) ?? throw new InvalidOperationException($"Resource {resourceName} not found."); + using var archive = SevenZipArchive.Open(resourceStream); + foreach (var entry in archive.Entries) + { + if (!entry.IsDirectory) + { + string outputPath = Path.Combine(outputDirectory, entry.Key); + Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + entry.WriteToFile(outputPath, new ExtractionOptions { ExtractFullPath = true, Overwrite = true }); + } + } + } + + public static async Task ExtractArchiveUsing7Zip(string path, string dest, List excludeFolder = null, string specificFile = null) { // Check if file exists in the root folder of the Manager