diff --git a/OpenRA.Mods.Common/InstallUtils.cs b/OpenRA.Mods.Common/InstallUtils.cs index 3835bd4daf..607f917761 100644 --- a/OpenRA.Mods.Common/InstallUtils.cs +++ b/OpenRA.Mods.Common/InstallUtils.cs @@ -39,6 +39,12 @@ namespace OpenRA.Mods.Common public readonly string MusicPackageMirrorList = null; public readonly int ShippedSoundtracks = 0; + /// InstallShield .cab File Ids, used to extract Mod specific files + public readonly int[] InstallShieldCABFileIds = { }; + + /// InstallShield .cab File Ids, used to extract Mod specific archives and extract contents of ExtractFilesFromCD + public readonly string[] InstallShieldCABFilePackageIds = { }; + public static Dictionary LoadFilesToExtract(MiniYaml yaml) { var md = yaml.ToDictionary(); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs index fa45caae50..01aa6d0745 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs @@ -12,6 +12,7 @@ using System; using System.IO; using System.Linq; using System.Threading; +using OpenRA.FileSystem; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic @@ -51,12 +52,26 @@ namespace OpenRA.Mods.Common.Widgets.Logic return installData.DiskTestFiles.All(f => File.Exists(Path.Combine(diskRoot, f))); } + bool IsTFD(string diskpath) + { + var test = File.Exists(Path.Combine(diskpath, "data1.hdr")); + var i = 0; + + while (test && i < 14) + test &= File.Exists(Path.Combine(diskpath, "data{0}.cab".F(++i))); + + return test; + } + void CheckForDisk() { var path = InstallUtils.GetMountedDisk(IsValidDisk); if (path != null) Install(path); + else if ((installData.InstallShieldCABFileIds.Length != 0 || installData.InstallShieldCABFilePackageIds.Length != 0) + && (path = InstallUtils.GetMountedDisk(IsTFD)) != null) + InstallTFD(Platform.ResolvePath(path, "data1.hdr")); else { insertDiskContainer.IsVisible = () => true; @@ -64,6 +79,63 @@ namespace OpenRA.Mods.Common.Widgets.Logic } } + void InstallTFD(string source) + { + backButton.IsDisabled = () => true; + retryButton.IsDisabled = () => true; + insertDiskContainer.IsVisible = () => false; + installingContainer.IsVisible = () => true; + progressBar.Percentage = 0; + + new Thread(() => + { + using (var cabExtractor = new InstallShieldCABExtractor(source)) + { + var denom = installData.InstallShieldCABFileIds.Length; + var extractFiles = installData.ExtractFilesFromCD; + + if (installData.InstallShieldCABFilePackageIds.Length > 0) + denom += extractFiles.SelectMany(x => x.Value).Count(); + + var installPercent = 100 / denom; + + foreach (uint index in installData.InstallShieldCABFileIds) + { + var filename = cabExtractor.FileName(index); + statusLabel.GetText = () => "Extracting {0}".F(filename); + var dest = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id, filename.ToLowerInvariant()); + cabExtractor.ExtractFile(index, dest); + progressBar.Percentage += installPercent; + } + + var ArchivesToExtract = installData.InstallShieldCABFilePackageIds.Select(x => x.Split(':')); + var destDir = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id); + var onError = (Action)(s => { }); + var overwrite = installData.OverwriteFiles; + + var onProgress = (Action)(s => Game.RunAfterTick(() => + { + progressBar.Percentage += installPercent; + + statusLabel.GetText = () => s; + })); + + foreach (var archive in ArchivesToExtract) + { + var filename = cabExtractor.FileName(uint.Parse(archive[0])); + statusLabel.GetText = () => "Extracting {0}".F(filename); + var destFile = Platform.ResolvePath("^", "Content", Game.ModData.Manifest.Mod.Id, filename.ToLowerInvariant()); + cabExtractor.ExtractFile(uint.Parse(archive[0]), destFile); + var annotation = archive.Length > 1 ? archive[1] : null; + InstallUtils.ExtractFromPackage(source, destFile, annotation, extractFiles, destDir, overwrite, onProgress, onError); + progressBar.Percentage += installPercent; + } + } + + continueLoading(); + }) { IsBackground = true }.Start(); + } + void Install(string source) { backButton.IsDisabled = () => true; diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 49cc307058..e8b4946741 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -153,6 +153,7 @@ ContentInstaller: .: conquer.mix, desert.mix, general.mix, scores.mix, sounds.mix, temperat.mix, winter.mix ShippedSoundtracks: 2 MusicPackageMirrorList: http://www.openra.net/packages/cnc-music-mirrors.txt + InstallShieldCABFileIds: 66, 45, 42, 65, 68, 67, 71, 47, 49, 60, 75, 73, 53 ServerTraits: LobbyCommands diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 5b47ef8fd0..203c5c5013 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -152,6 +152,8 @@ ContentInstaller: .: INSTALL/REDALERT.MIX ShippedSoundtracks: 2 MusicPackageMirrorList: http://www.openra.net/packages/ra-music-mirrors.txt + InstallShieldCABFilePackageIds: 105 + InstallShieldCABFileIds: 116 ServerTraits: LobbyCommands diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 9ae2ee8785..aa96accefe 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -201,6 +201,8 @@ ContentInstaller: .: cache.mix, conquer.mix, isosnow.mix, isotemp.mix, local.mix, sidec01.mix, sidec02.mix, sno.mix, snow.mix, sounds.mix, speech01.mix, tem.mix, temperat.mix ShippedSoundtracks: 2 MusicPackageMirrorList: http://www.openra.net/packages/ts-music-mirrors.txt + InstallShieldCABFilePackageIds: 332:CRC32 + InstallShieldCABFileIds: 323, 364 ServerTraits: LobbyCommands