diff --git a/OpenRA.Game/ContentInstaller.cs b/OpenRA.Game/ContentInstaller.cs index 49763093d2..34d096f172 100644 --- a/OpenRA.Game/ContentInstaller.cs +++ b/OpenRA.Game/ContentInstaller.cs @@ -15,11 +15,14 @@ namespace OpenRA // Referenced from ModMetadata, so needs to be in OpenRA.Game :( public class ContentInstaller : IGlobalModData { + public enum FilenameCase { Input, ForceLower, ForceUpper } + public readonly string[] TestFiles = { }; public readonly string[] DiskTestFiles = { }; public readonly string PackageToExtractFromCD = null; public readonly bool OverwriteFiles = true; + public readonly FilenameCase OutputFilenameCase = FilenameCase.ForceLower; public readonly Dictionary CopyFilesFromCD = new Dictionary(); public readonly Dictionary ExtractFilesFromCD = new Dictionary(); diff --git a/OpenRA.Mods.Common/InstallUtils.cs b/OpenRA.Mods.Common/InstallUtils.cs index 92d2c9c2e8..275e72d449 100644 --- a/OpenRA.Mods.Common/InstallUtils.cs +++ b/OpenRA.Mods.Common/InstallUtils.cs @@ -37,9 +37,26 @@ namespace OpenRA.Mods.Common return volumes.FirstOrDefault(isValidDisk); } + static string GetFileName(string path, ContentInstaller.FilenameCase caseModifier) + { + // Gets the file path, splitting on both / and \ + var index = path.LastIndexOfAny(new[] { '\\', '/' }); + var output = path.Substring(index + 1); + + switch (caseModifier) + { + case ContentInstaller.FilenameCase.ForceLower: + return output.ToLowerInvariant(); + case ContentInstaller.FilenameCase.ForceUpper: + return output.ToUpperInvariant(); + default: + return output; + } + } + // TODO: The package should be mounted into its own context to avoid name collisions with installed files public static bool ExtractFromPackage(string srcPath, string package, string annotation, Dictionary filesByDirectory, - string destPath, bool overwrite, Action onProgress, Action onError) + string destPath, bool overwrite, ContentInstaller.FilenameCase caseModifier, Action onProgress, Action onError) { Directory.CreateDirectory(destPath); @@ -55,7 +72,7 @@ namespace OpenRA.Mods.Common foreach (var file in directory.Value) { var containingDir = Path.Combine(destPath, targetDir); - var dest = Path.Combine(containingDir, file.ToLowerInvariant()); + var dest = Path.Combine(containingDir, GetFileName(file, caseModifier)); if (File.Exists(dest)) { if (overwrite) @@ -83,7 +100,7 @@ namespace OpenRA.Mods.Common } public static bool CopyFiles(string srcPath, Dictionary files, string destPath, - bool overwrite, Action onProgress, Action onError) + bool overwrite, ContentInstaller.FilenameCase caseModifier, Action onProgress, Action onError) { Directory.CreateDirectory(destPath); @@ -100,9 +117,9 @@ namespace OpenRA.Mods.Common return false; } - var destFile = Path.GetFileName(file); + var destFile = GetFileName(file, caseModifier); var containingDir = Path.Combine(destPath, targetDir); - var dest = Path.Combine(containingDir, destFile.ToLowerInvariant()); + var dest = Path.Combine(containingDir, destFile); if (File.Exists(dest) && !overwrite) { Log.Write("debug", "Skipping {0}".F(dest)); diff --git a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs index 1d5b2be5cf..95cf3deb31 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Installation/InstallFromCDLogic.cs @@ -132,7 +132,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var destFile = Platform.ResolvePath("^", "Content", modId, 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); + InstallUtils.ExtractFromPackage(source, destFile, annotation, extractFiles, destDir, overwrite, installData.OutputFilenameCase, onProgress, onError); progressBar.Percentage += installPercent; } } @@ -183,7 +183,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic { try { - if (!InstallUtils.CopyFiles(source, copyFiles, dest, overwrite, onProgress, onError)) + if (!InstallUtils.CopyFiles(source, copyFiles, dest, overwrite, installData.OutputFilenameCase, onProgress, onError)) { onError("Copying files from CD failed."); return; @@ -191,7 +191,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (!string.IsNullOrEmpty(extractPackage)) { - if (!InstallUtils.ExtractFromPackage(source, extractPackage, annotation, extractFiles, dest, overwrite, onProgress, onError)) + if (!InstallUtils.ExtractFromPackage(source, extractPackage, annotation, extractFiles, dest, + overwrite, installData.OutputFilenameCase, onProgress, onError)) { onError("Extracting files from CD failed."); return; diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 673230bf89..736461a12b 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -130,6 +130,7 @@ LoadScreen: LogoStripeLoadScreen Text: Filling Crates..., Breeding Sandworms..., Fuelling carryalls..., Deploying harvesters..., Preparing 'thopters..., Summoning mentats... ContentInstaller: + OutputFilenameCase: ForceUpper # TODO: check if DATA.R8 is at 1.03 patch level with 4840 frames TestFiles: ^Content/d2k/BLOXBASE.R8, ^Content/d2k/BLOXBAT.R8, ^Content/d2k/BLOXBGBS.R8, ^Content/d2k/BLOXICE.R8, ^Content/d2k/BLOXTREE.R8, ^Content/d2k/BLOXWAST.R8, ^Content/d2k/DATA.R8, ^Content/d2k/SOUND.RS, ^Content/d2k/PALETTE.BIN PackageMirrorList: http://www.openra.net/packages/d2k-103-mirrors.txt