From 83c026e12b7d74df648788982a6202cf7c842af2 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 4 May 2011 13:41:27 +1200 Subject: [PATCH] Don't rely on the utility for ra package extraction. Untested. --- OpenRA.Game/Utilities.cs | 32 ------- .../Widgets/Delegates/GameInitDelegate.cs | 84 +++++++++++++------ 2 files changed, 60 insertions(+), 56 deletions(-) diff --git a/OpenRA.Game/Utilities.cs b/OpenRA.Game/Utilities.cs index ebc96a70b5..6baf5329aa 100644 --- a/OpenRA.Game/Utilities.cs +++ b/OpenRA.Game/Utilities.cs @@ -23,11 +23,6 @@ namespace OpenRA Utility = utility; } - public void InstallRAFilesAsync(string cdPath, string path, Action parseOutput, Action onComplete) - { - ExecuteUtilityAsync("--install-ra-packages \"{0}\" \"{1}\"".F(cdPath, path), parseOutput, onComplete); - } - public void PromptFilepathAsync(string title, Action withPath) { ExecuteUtility("--display-filepicker \"{0}\"".F(title), withPath); @@ -48,32 +43,5 @@ namespace OpenRA }; p.Start(); } - - void ExecuteUtilityAsync(string args, Action parseOutput, Action onComplete) - { - Process p = new Process(); - p.StartInfo.FileName = Utility; - p.StartInfo.Arguments = "{0} --SupportDir \"{1}\"".F(args, Game.SupportDir); - p.StartInfo.UseShellExecute = false; - p.StartInfo.CreateNoWindow = true; - p.StartInfo.RedirectStandardOutput = true; - p.Start(); - - var t = new Thread( _ => - { - using (var reader = p.StandardOutput) - { - // This is wrong, chrisf knows why - while (!p.HasExited) - { - string s = reader.ReadLine(); - if (string.IsNullOrEmpty(s)) continue; - parseOutput(s); - } - } - onComplete(); - }) { IsBackground = true }; - t.Start(); - } } } diff --git a/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs index 4d2b321618..d78c7e4859 100755 --- a/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs @@ -91,7 +91,6 @@ namespace OpenRA.Mods.RA.Widgets.Delegates void InstallFromCD(string path) { var window = Widget.OpenWindow("INIT_COPY"); - var status = window.GetWidget("STATUS"); var progress = window.GetWidget("PROGRESS"); progress.Indeterminate = true; @@ -99,30 +98,11 @@ namespace OpenRA.Mods.RA.Widgets.Delegates window.GetWidget("CANCEL").IsVisible = () => false; window.GetWidget("CANCEL").OnMouseUp = mi => { ShowInstallMethodDialog(); return true; }; window.GetWidget("RETRY").OnMouseUp = mi => PromptForCD(); - - status.GetText = () => "Copying..."; - var error = false; - Action parseOutput = s => - { - if (s.Substring(0,5) == "Error") - { - error = true; - ShowDownloadError(window, s); - } - if (s.Substring(0,6) == "Status") - window.GetWidget("STATUS").GetText = () => s.Substring(7).Trim(); - }; - Action onComplete = () => - { - if (!error) - Game.RunAfterTick(ContinueLoading); - }; - - if (Info.InstallMode == "ra") - Game.Utilities.InstallRAFilesAsync(path, FileSystem.SpecialPackageRoot+Info.PackagePath, parseOutput, onComplete); - else + if (Info.InstallMode != "ra") ShowDownloadError(window, "Installing from CD not supported"); + else if (InstallRAPackages(window, path, FileSystem.SpecialPackageRoot+Info.PackagePath)) + Game.RunAfterTick(ContinueLoading); } void ShowDownloadDialog() @@ -213,6 +193,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates ShowDownloadError(window, "Invalid path: "+zipFile); return false; } + var status = window.GetWidget("STATUS"); List extracted = new List(); try @@ -223,12 +204,67 @@ namespace OpenRA.Mods.RA.Widgets.Delegates { foreach(var f in extracted) File.Delete(f); - ShowDownloadError(window, "Archive corrupt: "+zipFile); + ShowDownloadError(window, "Archive corrupt"); return false; } status.GetText = () => "Extraction complete"; return true; } + + // TODO: The package should be mounted into its own context to avoid name collisions with installed files + bool ExtractFromPackage(Widget window, string srcPath, string package, string[] files, string destPath) + { + var status = window.GetWidget("STATUS"); + + if (!Directory.Exists(destPath)) + Directory.CreateDirectory(destPath); + + if (!Directory.Exists(srcPath)) { ShowDownloadError(window, "Cannot find "+package); return false; } + FileSystem.Mount(srcPath); + if (!FileSystem.Exists(package)) { ShowDownloadError(window, "Cannot find "+package); return false; } + FileSystem.Mount(package); + + foreach (string s in files) + { + var destFile = Path.Combine(destPath, s); + using (var sourceStream = FileSystem.Open(s)) + using (var destStream = File.Create(destFile)) + { + status.GetText = () => "Extracting "+s; + destStream.Write(sourceStream.ReadAllBytes()); + } + } + + status.GetText = () => "Extraction complete"; + return true; + } + + bool CopyFiles(Widget window, string srcPath, string[] files, string destPath) + { + var status = window.GetWidget("STATUS"); + + foreach (var file in files) + { + var fromPath = Path.Combine(srcPath, file); + if (!File.Exists(fromPath)) + { + ShowDownloadError(window, "Cannot find "+file); + return false; + } + status.GetText = () => "Extracting "+file.ToLowerInvariant(); + File.Copy(fromPath, Path.Combine(destPath, Path.GetFileName(file).ToLowerInvariant()), true); + } + return true; + } + + bool InstallRAPackages(Widget window, string source, string dest) + { + if (!CopyFiles(window, Path.Combine(source, "INSTALL"), new string[] {"REDALERT.MIX"}, dest)) + return false; + return ExtractFromPackage(window, source, "MAIN.MIX", + new string[] { "conquer.mix", "russian.mix", "allies.mix", "sounds.mix", + "scores.mix", "snow.mix", "interior.mix", "temperat.mix" }, dest); + } } static class InstallUtils