diff --git a/OpenRA.Game/Graphics/CursorProvider.cs b/OpenRA.Game/Graphics/CursorProvider.cs index a93420f3ef..7607a58c2f 100644 --- a/OpenRA.Game/Graphics/CursorProvider.cs +++ b/OpenRA.Game/Graphics/CursorProvider.cs @@ -38,10 +38,7 @@ namespace OpenRA.Graphics Game.modData.LoadScreen.Display(); foreach (var sequence in cursor.Nodes) - { - Console.WriteLine(sequence.Key); cursors.Add(sequence.Key, new CursorSequence(cursorSrc, cursor.Value, sequence.Value)); - } } public static bool HasCursorSequence(string cursor) diff --git a/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs b/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs index 84656627e2..49eca025a1 100755 --- a/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs +++ b/OpenRA.Mods.RA/Widgets/Delegates/GameInitDelegate.cs @@ -17,12 +17,16 @@ using System.Diagnostics; using System; using System.Net; using System.ComponentModel; +using ICSharpCode.SharpZipLib; +using ICSharpCode.SharpZipLib.Zip; +using System.IO; namespace OpenRA.Mods.RA.Widgets.Delegates { public class GameInitDelegate : IWidgetDelegate { GameInitInfoWidget Info; + Widget window; [ObjectCreator.UseCtor] public GameInitDelegate([ObjectCreator.Param] Widget widget) @@ -64,7 +68,7 @@ namespace OpenRA.Mods.RA.Widgets.Delegates void ShowInstallMethodDialog() { - var window = Widget.OpenWindow("INIT_CHOOSEINSTALL"); + window = Widget.OpenWindow("INIT_CHOOSEINSTALL"); window.GetWidget("DOWNLOAD").OnMouseUp = mi => { ShowDownloadDialog(); return true; }; window.GetWidget("FROMCD").OnMouseUp = mi => { @@ -77,22 +81,106 @@ namespace OpenRA.Mods.RA.Widgets.Delegates void ShowDownloadDialog() { - var window = Widget.OpenWindow("INIT_DOWNLOAD"); + window = Widget.OpenWindow("INIT_DOWNLOAD"); var status = window.GetWidget("STATUS"); status.GetText = () => "Initializing..."; - var progress = window.GetWidget("PROGRESS"); - - var dl = DownloadUrl(Info.PackageURL, Info.PackagePath, - (_,i) => { - status.GetText = () => "Downloading {1}/{2} kB ({0}%)".F(i.ProgressPercentage, i.BytesReceived/1024, i.TotalBytesToReceive/1024); - progress.Percentage = i.ProgressPercentage; - }, - (_,i) => status.GetText = () => "Download Complete"); - window.GetWidget("CANCEL").OnMouseUp = mi => { CancelDownload(dl); ShowInstallMethodDialog(); return true; }; + // TODO: Download to a temp location or the support dir + var file = Info.PackageName; + + var progress = window.GetWidget("PROGRESS"); + + window.GetWidget("EXTRACT").OnMouseUp = mi => + { + if (ExtractZip(file, Info.PackagePath)) + ContinueLoading(Info); + return true; + }; + + + if (File.Exists(file)) + { + window.GetWidget("EXTRACT").IsVisible = () => true; + status.GetText = () => "Download Cached"; + progress.Percentage = 100; + } + else + { + var dl = DownloadUrl(Info.PackageURL, file, + (_,i) => { + status.GetText = () => "Downloading {1}/{2} kB ({0}%)".F(i.ProgressPercentage, i.BytesReceived/1024, i.TotalBytesToReceive/1024); + progress.Percentage = i.ProgressPercentage; + }, + (_,i) => { + if (i.Error != null) + { + ShowDownloadError(i.Error.Message); + } + else + { + status.GetText = () => "Download Complete"; + window.GetWidget("EXTRACT").IsVisible = () => true; + window.GetWidget("CANCEL").IsVisible = () => false; + } + } + ); + window.GetWidget("CANCEL").IsVisible = () => true; + window.GetWidget("RETRY").IsVisible = () => true; + + window.GetWidget("CANCEL").OnMouseUp = mi => { dl.CancelAsync(); ShowInstallMethodDialog(); return true; }; + window.GetWidget("RETRY").OnMouseUp = mi => { dl.CancelAsync(); ShowDownloadDialog(); return true; }; + } + } + + void ShowDownloadError(string e) + { + window.GetWidget("STATUS").GetText = () => e; + window.GetWidget("RETRY").IsVisible = () => true; + window.GetWidget("CANCEL").IsVisible = () => true; } + // TODO: This needs to live on a different process if we want to run it as root + public bool ExtractZip(string zipFile, string path) + { + if (!File.Exists(zipFile)) { ShowDownloadError("Download Corrupted"); return false; } + List extracted = new List(); + try + { + ZipEntry entry; + var z = new ZipInputStream(File.OpenRead(zipFile)); + while ((entry = z.GetNextEntry()) != null) + { + if (!entry.IsFile) continue; + if (!Directory.Exists(Path.Combine(path, Path.GetDirectoryName(entry.Name)))) + Directory.CreateDirectory(Path.Combine(path, Path.GetDirectoryName(entry.Name))); + + window.GetWidget("STATUS").GetText = () => "Status: Extracting {0}".F(entry.Name); + + var destPath = path + Path.DirectorySeparatorChar + entry.Name; + Console.WriteLine("Extracting to {0}",destPath); + extracted.Add(path); + using (var f = File.Create(destPath)) + { + int bufSize = 2048; + byte[] buf = new byte[bufSize]; + while ((bufSize = z.Read(buf, 0, buf.Length)) > 0) + f.Write(buf, 0, bufSize); + } + } + z.Close(); + } + catch (SharpZipBaseException) + { + foreach(var f in extracted) + File.Delete(f); + + ShowDownloadError("Download Corrupted"); + return false; + } + return true; + } + void SelectDisk(Action withPath) { Process p = new Process(); @@ -122,16 +210,10 @@ namespace OpenRA.Mods.RA.Widgets.Delegates wc.DownloadProgressChanged += onProgress; wc.DownloadFileCompleted += onComplete; - wc.DownloadFileCompleted += (_,a) => {}; + wc.DownloadFileCompleted += (_,a) => {Game.OnQuit -= () => wc.CancelAsync();}; wc.DownloadFileAsync(new Uri(url), path); - Game.OnQuit += () => CancelDownload(wc); + Game.OnQuit += () => wc.CancelAsync(); return wc; } - - public static void CancelDownload(WebClient wc) - { - Game.OnQuit -= () => CancelDownload(wc); - wc.CancelAsync(); - } } } diff --git a/OpenRA.Mods.RA/Widgets/GameInitInfoWidget.cs b/OpenRA.Mods.RA/Widgets/GameInitInfoWidget.cs index 063d1d9eaf..a801db36ae 100755 --- a/OpenRA.Mods.RA/Widgets/GameInitInfoWidget.cs +++ b/OpenRA.Mods.RA/Widgets/GameInitInfoWidget.cs @@ -17,6 +17,7 @@ namespace OpenRA.Mods.RA.Widgets public string TestFile; public string GameTitle; public string PackageURL; + public string PackageName; public string PackagePath; public override void DrawInner() {} diff --git a/mods/cnc/chrome/gameinit.yaml b/mods/cnc/chrome/gameinit.yaml index ec1bd2a943..f2589807b7 100644 --- a/mods/cnc/chrome/gameinit.yaml +++ b/mods/cnc/chrome/gameinit.yaml @@ -1,9 +1,11 @@ GameInitInfo@INIT_SETUP: Id:INIT_SETUP - TestFile: fakefile.mix + TestFile: conquer.mix GameTitle: Command & Conquer - PackageURL:http://open-ra.org/get-dependency.php?file=cnc-packages - PackagePath:cnc-packages.zip +# PackageURL:http://open-ra.org/get-dependency.php?file=cnc-packages + PackageURL:http://localhost/~paul/cnc-packages.zip + PackageName:cnc-packages.zip + PackagePath:mods/cnc/packages Delegate:GameInitDelegate Background@INIT_CHOOSEINSTALL: @@ -78,21 +80,40 @@ Background@INIT_DOWNLOAD: ProgressBar@PROGRESS: Id:PROGRESS X:50 - Y:65 + Y:55 Width:PARENT_RIGHT - 100 Height:25 Label@STATUS: Id:STATUS X:50 - Y:PARENT_BOTTOM - 50 + Y:80 Width:PARENT_RIGHT - 100 Height:25 Align:Left + Button@RETRY: + Id:RETRY + X:PARENT_RIGHT - 280 + Y:PARENT_BOTTOM - 45 + Width:120 + Height:25 + Visible: false + Text:Retry + Bold:True Button@CANCEL: Id:CANCEL X:PARENT_RIGHT - 140 Y:PARENT_BOTTOM - 45 Width:120 Height:25 + Visible: false Text:Cancel Bold:True + Button@EXTRACT: + Id:EXTRACT + X:PARENT_RIGHT - 140 + Y:PARENT_BOTTOM - 45 + Width:120 + Height:25 + Visible: false + Text:Extract + Bold:True \ No newline at end of file