diff --git a/OpenRA.Game/FileSystem/BagFile.cs b/OpenRA.Game/FileSystem/BagFile.cs index 6fe5287a31..649879f230 100644 --- a/OpenRA.Game/FileSystem/BagFile.cs +++ b/OpenRA.Game/FileSystem/BagFile.cs @@ -21,15 +21,15 @@ namespace OpenRA.FileSystem { public sealed class BagFile : IReadOnlyPackage { - readonly string bagFilename; + public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } + readonly Stream s; - readonly int bagFilePriority; readonly Dictionary index; - public BagFile(FileSystem context, string filename, int priority) + public BagFile(FileSystem context, string filename) { - bagFilename = filename; - bagFilePriority = priority; + Name = filename; // A bag file is always accompanied with an .idx counterpart // For example: audio.bag requires the audio.idx file @@ -47,10 +47,7 @@ namespace OpenRA.FileSystem s = context.Open(filename); } - public int Priority { get { return 1000 + bagFilePriority; } } - public string Name { get { return bagFilename; } } - - public Stream GetContent(string filename) + public Stream GetStream(string filename) { IdxEntry entry; if (!index.TryGetValue(filename, out entry)) @@ -116,16 +113,11 @@ namespace OpenRA.FileSystem return mergedStream; } - public bool Exists(string filename) + public bool Contains(string filename) { return index.ContainsKey(filename); } - public IEnumerable AllFileNames() - { - return index.Keys; - } - public void Dispose() { s.Dispose(); diff --git a/OpenRA.Game/FileSystem/BigFile.cs b/OpenRA.Game/FileSystem/BigFile.cs index 8bb6b69025..4f54facfad 100644 --- a/OpenRA.Game/FileSystem/BigFile.cs +++ b/OpenRA.Game/FileSystem/BigFile.cs @@ -18,14 +18,14 @@ namespace OpenRA.FileSystem public sealed class BigFile : IReadOnlyPackage { public string Name { get; private set; } - public int Priority { get; private set; } - readonly Dictionary entries = new Dictionary(); + public IEnumerable Contents { get { return index.Keys; } } + + readonly Dictionary index = new Dictionary(); readonly Stream s; - public BigFile(FileSystem context, string filename, int priority) + public BigFile(FileSystem context, string filename) { Name = filename; - Priority = priority; s = context.Open(filename); try @@ -47,7 +47,7 @@ namespace OpenRA.FileSystem for (var i = 0; i < entryCount; i++) { var entry = new Entry(s); - entries.Add(entry.Path, entry); + index.Add(entry.Path, entry); } } catch @@ -86,19 +86,14 @@ namespace OpenRA.FileSystem } } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { - return entries[filename].GetData(); + return index[filename].GetData(); } - public bool Exists(string filename) + public bool Contains(string filename) { - return entries.ContainsKey(filename); - } - - public IEnumerable AllFileNames() - { - return entries.Keys; + return index.ContainsKey(filename); } public void Dispose() diff --git a/OpenRA.Game/FileSystem/D2kSoundResources.cs b/OpenRA.Game/FileSystem/D2kSoundResources.cs index 369b9ddeb4..ef06a46c58 100644 --- a/OpenRA.Game/FileSystem/D2kSoundResources.cs +++ b/OpenRA.Game/FileSystem/D2kSoundResources.cs @@ -28,16 +28,15 @@ namespace OpenRA.FileSystem } } - readonly Stream s; + public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } - readonly string filename; - readonly int priority; + readonly Stream s; readonly Dictionary index = new Dictionary(); - public D2kSoundResources(FileSystem context, string filename, int priority) + public D2kSoundResources(FileSystem context, string filename) { - this.filename = filename; - this.priority = priority; + Name = filename; s = context.Open(filename); try @@ -58,7 +57,7 @@ namespace OpenRA.FileSystem } } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { Entry e; if (!index.TryGetValue(filename, out e)) @@ -68,20 +67,11 @@ namespace OpenRA.FileSystem return new MemoryStream(s.ReadBytes((int)e.Length)); } - public bool Exists(string filename) + public bool Contains(string filename) { return index.ContainsKey(filename); } - public IEnumerable AllFileNames() - { - return index.Keys; - } - - public string Name { get { return filename; } } - - public int Priority { get { return 1000 + priority; } } - public void Dispose() { s.Dispose(); diff --git a/OpenRA.Game/FileSystem/FileSystem.cs b/OpenRA.Game/FileSystem/FileSystem.cs index 35b59fbc40..aa700a49e8 100644 --- a/OpenRA.Game/FileSystem/FileSystem.cs +++ b/OpenRA.Game/FileSystem/FileSystem.cs @@ -19,61 +19,54 @@ namespace OpenRA.FileSystem { public class FileSystem { - public readonly List MountedPackages = new List(); + public IEnumerable MountedPackages { get { return mountedPackages.Keys; } } + readonly Dictionary mountedPackages = new Dictionary(); static readonly Dictionary AssemblyCache = new Dictionary(); - - int order; Cache> fileIndex = new Cache>(_ => new List()); - public IReadWritePackage CreatePackage(string filename, int order, Dictionary content) + public IReadWritePackage CreatePackage(string filename, Dictionary content) { if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order, content); + return new ZipFile(this, filename, content); if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order, content); + return new ZipFile(this, filename, content); - return new Folder(filename, order, content); + return new Folder(filename, content); } - public IReadOnlyPackage OpenPackage(string filename, int order) + public IReadOnlyPackage OpenPackage(string filename) { if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) - return new MixFile(this, filename, order); + return new MixFile(this, filename); if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order); + return new ZipFile(this, filename); if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order); + return new ZipFile(this, filename); if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase)) - return new D2kSoundResources(this, filename, order); + return new D2kSoundResources(this, filename); if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) - return new InstallShieldPackage(this, filename, order); + return new InstallShieldPackage(this, filename); if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase)) - return new PakFile(this, filename, order); + return new PakFile(this, filename); if (filename.EndsWith(".big", StringComparison.InvariantCultureIgnoreCase)) - return new BigFile(this, filename, order); + return new BigFile(this, filename); if (filename.EndsWith(".bag", StringComparison.InvariantCultureIgnoreCase)) - return new BagFile(this, filename, order); + return new BagFile(this, filename); if (filename.EndsWith(".hdr", StringComparison.InvariantCultureIgnoreCase)) - return new InstallShieldCABExtractor(this, filename, order); + return new InstallShieldCABExtractor(this, filename); - return new Folder(filename, order); + return new Folder(filename); } - public IReadWritePackage OpenWritablePackage(string filename, int order) + public IReadWritePackage OpenWritablePackage(string filename) { if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order); + return new ZipFile(this, filename); if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) - return new ZipFile(this, filename, order); + return new ZipFile(this, filename); - return new Folder(filename, order); - } - - public void Mount(IReadOnlyPackage mount) - { - if (!MountedPackages.Contains(mount)) - MountedPackages.Add(mount); + return new Folder(filename); } public void Mount(string name) @@ -84,8 +77,7 @@ namespace OpenRA.FileSystem name = Platform.ResolvePath(name); - Action a = () => MountInner(OpenPackage(name, order++)); - + Action a = () => Mount(OpenPackage(name)); if (optional) try { a(); } catch { } @@ -93,44 +85,61 @@ namespace OpenRA.FileSystem a(); } - void MountInner(IReadOnlyPackage package) + public void Mount(IReadOnlyPackage package) { - MountedPackages.Add(package); - - foreach (var filename in package.AllFileNames()) + var mountCount = 0; + if (mountedPackages.TryGetValue(package, out mountCount)) { - var packageList = fileIndex[filename]; - if (!packageList.Contains(package)) - packageList.Add(package); + // Package is already mounted + // Increment the mount count and bump up the file loading priority + mountedPackages[package] = mountCount + 1; + foreach (var filename in package.Contents) + { + fileIndex[filename].Remove(package); + fileIndex[filename].Add(package); + } + } + else + { + // Mounting the package for the first time + mountedPackages.Add(package, 1); + foreach (var filename in package.Contents) + fileIndex[filename].Add(package); } } public bool Unmount(IReadOnlyPackage package) { - foreach (var packagesForFile in fileIndex.Values) - packagesForFile.RemoveAll(p => p == package); + var mountCount = 0; + if (!mountedPackages.TryGetValue(package, out mountCount)) + return false; - if (MountedPackages.Contains(package)) + if (--mountCount <= 0) + { + foreach (var packagesForFile in fileIndex.Values) + packagesForFile.RemoveAll(p => p == package); + + mountedPackages.Remove(package); package.Dispose(); + } + else + mountedPackages[package] = mountCount; - return MountedPackages.RemoveAll(p => p == package) > 0; + return true; } public void UnmountAll() { - foreach (var package in MountedPackages) + foreach (var package in mountedPackages.Keys) package.Dispose(); - MountedPackages.Clear(); + mountedPackages.Clear(); fileIndex = new Cache>(_ => new List()); } public void LoadFromManifest(Manifest manifest) { UnmountAll(); - foreach (var dir in manifest.Folders) - Mount(dir); - foreach (var pkg in manifest.Packages) Mount(pkg); } @@ -138,11 +147,10 @@ namespace OpenRA.FileSystem Stream GetFromCache(string filename) { var package = fileIndex[filename] - .Where(x => x.Exists(filename)) - .MinByOrDefault(x => x.Priority); + .LastOrDefault(x => x.Contains(filename)); if (package != null) - return package.GetContent(filename); + return package.GetStream(filename); return null; } @@ -182,13 +190,13 @@ namespace OpenRA.FileSystem // Ask each package individually IReadOnlyPackage package; if (explicitPackage && !string.IsNullOrEmpty(packageName)) - package = MountedPackages.Where(x => x.Name == packageName).MaxByOrDefault(x => x.Priority); + package = mountedPackages.Keys.LastOrDefault(x => x.Name == packageName); else - package = MountedPackages.Where(x => x.Exists(filename)).MaxByOrDefault(x => x.Priority); + package = mountedPackages.Keys.LastOrDefault(x => x.Contains(filename)); if (package != null) { - s = package.GetContent(filename); + s = package.GetStream(filename); return true; } @@ -204,10 +212,10 @@ namespace OpenRA.FileSystem var divide = name.Split(':'); var packageName = divide.First(); var filename = divide.Last(); - return MountedPackages.Where(n => n.Name == packageName).Any(f => f.Exists(filename)); + return mountedPackages.Keys.Where(n => n.Name == packageName).Any(f => f.Contains(filename)); } else - return MountedPackages.Any(f => f.Exists(name)); + return mountedPackages.Keys.Any(f => f.Contains(name)); } public static Assembly ResolveAssembly(object sender, ResolveEventArgs e) diff --git a/OpenRA.Game/FileSystem/Folder.cs b/OpenRA.Game/FileSystem/Folder.cs index 1fcef789d9..e3099341b6 100644 --- a/OpenRA.Game/FileSystem/Folder.cs +++ b/OpenRA.Game/FileSystem/Folder.cs @@ -16,47 +16,46 @@ namespace OpenRA.FileSystem public sealed class Folder : IReadWritePackage { readonly string path; - readonly int priority; // Create a new folder package - public Folder(string path, int priority, Dictionary contents) + public Folder(string path, Dictionary contents) { this.path = path; - this.priority = priority; if (Directory.Exists(path)) Directory.Delete(path, true); Write(contents); } - public Folder(string path, int priority) + public Folder(string path) { this.path = path; - this.priority = priority; if (!Directory.Exists(path)) Directory.CreateDirectory(path); } - public Stream GetContent(string filename) + public string Name { get { return path; } } + + public IEnumerable Contents + { + get + { + foreach (var filename in Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly)) + yield return Path.GetFileName(filename); + } + } + + public Stream GetStream(string filename) { try { return File.OpenRead(Path.Combine(path, filename)); } catch { return null; } } - public IEnumerable AllFileNames() - { - foreach (var filename in Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly)) - yield return Path.GetFileName(filename); - } - - public bool Exists(string filename) + public bool Contains(string filename) { return File.Exists(Path.Combine(path, filename)); } - public int Priority { get { return priority; } } - public string Name { get { return path; } } - public void Write(Dictionary contents) { if (!Directory.Exists(path)) diff --git a/OpenRA.Game/FileSystem/IPackage.cs b/OpenRA.Game/FileSystem/IPackage.cs index cb9c54d1c5..2e27fc0fb9 100644 --- a/OpenRA.Game/FileSystem/IPackage.cs +++ b/OpenRA.Game/FileSystem/IPackage.cs @@ -16,11 +16,10 @@ namespace OpenRA.FileSystem { public interface IReadOnlyPackage : IDisposable { - Stream GetContent(string filename); - bool Exists(string filename); - IEnumerable AllFileNames(); - int Priority { get; } string Name { get; } + IEnumerable Contents { get; } + Stream GetStream(string filename); + bool Contains(string filename); } public interface IReadWritePackage : IReadOnlyPackage diff --git a/OpenRA.Game/FileSystem/InstallShieldCABExtractor.cs b/OpenRA.Game/FileSystem/InstallShieldCABExtractor.cs index 17756bd979..134657a854 100644 --- a/OpenRA.Game/FileSystem/InstallShieldCABExtractor.cs +++ b/OpenRA.Game/FileSystem/InstallShieldCABExtractor.cs @@ -329,25 +329,22 @@ namespace OpenRA.FileSystem readonly List directoryTable; readonly Dictionary directoryNames = new Dictionary(); readonly Dictionary fileDescriptors = new Dictionary(); - readonly Dictionary fileLookup = new Dictionary(); + readonly Dictionary index = new Dictionary(); readonly FileSystem context; - int priority; - string commonName; - public int Priority { get { return priority; } } - public string Name { get { return commonName; } } + public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } - public InstallShieldCABExtractor(FileSystem context, string hdrFilename, int priority = -1) + public InstallShieldCABExtractor(FileSystem context, string hdrFilename) { var fileGroups = new List(); var fileGroupOffsets = new List(); hdrFile = context.Open(hdrFilename); - this.priority = priority; this.context = context; // Strips archive number AND file extension - commonName = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", ""); + Name = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", ""); var signature = hdrFile.ReadUInt32(); if (signature != 0x28635349) @@ -383,12 +380,12 @@ namespace OpenRA.FileSystem hdrFile.Seek(commonHeader.CabDescriptorOffset + cabDescriptor.FileTableOffset + cabDescriptor.FileTableOffset2, SeekOrigin.Begin); foreach (var fileGroup in fileGroups) { - for (var index = fileGroup.FirstFile; index <= fileGroup.LastFile; ++index) + for (var i = fileGroup.FirstFile; i <= fileGroup.LastFile; ++i) { - AddFileDescriptorToList(index); - var fileDescriptor = fileDescriptors[index]; + AddFileDescriptorToList(i); + var fileDescriptor = fileDescriptors[i]; var fullFilePath = "{0}\\{1}\\{2}".F(fileGroup.Name, DirectoryName(fileDescriptor.DirectoryIndex), fileDescriptor.Filename); - fileLookup.Add(fullFilePath, index); + index.Add(fullFilePath, i); } } } @@ -407,9 +404,9 @@ namespace OpenRA.FileSystem return test; } - public bool Exists(string filename) + public bool Contains(string filename) { - return fileLookup.ContainsKey(filename); + return index.ContainsKey(filename); } public uint DirectoryCount() @@ -465,7 +462,7 @@ namespace OpenRA.FileSystem var output = new MemoryStream((int)fileDes.ExpandedSize); - using (var reader = new CabReader(context, fileDes, index, commonName)) + using (var reader = new CabReader(context, fileDes, index, Name)) reader.CopyTo(output); if (output.Length != fileDes.ExpandedSize) @@ -490,21 +487,16 @@ namespace OpenRA.FileSystem if ((fileDes.Flags & FileObfuscated) != 0) throw new NotImplementedException("Haven't implemented obfuscated files"); - using (var reader = new CabReader(context, fileDes, index, commonName)) + using (var reader = new CabReader(context, fileDes, index, Name)) reader.CopyTo(output); if (output.Length != fileDes.ExpandedSize) throw new Exception("Did not fully extract Expected = {0}, Got = {1}".F(fileDes.ExpandedSize, output.Length)); } - public Stream GetContent(string fileName) + public Stream GetStream(string fileName) { - return GetContentById(fileLookup[fileName]); - } - - public IEnumerable AllFileNames() - { - return fileLookup.Keys; + return GetContentById(index[fileName]); } public void Dispose() diff --git a/OpenRA.Game/FileSystem/InstallShieldPackage.cs b/OpenRA.Game/FileSystem/InstallShieldPackage.cs index 240cb88475..8511684570 100644 --- a/OpenRA.Game/FileSystem/InstallShieldPackage.cs +++ b/OpenRA.Game/FileSystem/InstallShieldPackage.cs @@ -29,16 +29,16 @@ namespace OpenRA.FileSystem } } + public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } + readonly Dictionary index = new Dictionary(); readonly Stream s; readonly long dataStart = 255; - readonly int priority; - readonly string filename; - public InstallShieldPackage(FileSystem context, string filename, int priority) + public InstallShieldPackage(FileSystem context, string filename) { - this.filename = filename; - this.priority = priority; + Name = filename; s = context.Open(filename); try @@ -106,7 +106,7 @@ namespace OpenRA.FileSystem s.Position += chunkSize - nameLength - 30; } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { Entry e; if (!index.TryGetValue(filename, out e)) @@ -118,19 +118,11 @@ namespace OpenRA.FileSystem return new MemoryStream(Blast.Decompress(data)); } - public IEnumerable AllFileNames() - { - return index.Keys; - } - - public bool Exists(string filename) + public bool Contains(string filename) { return index.ContainsKey(filename); } - public int Priority { get { return 2000 + priority; } } - public string Name { get { return filename; } } - public void Dispose() { s.Dispose(); diff --git a/OpenRA.Game/FileSystem/MixFile.cs b/OpenRA.Game/FileSystem/MixFile.cs index cae11109f8..aa6d3f374c 100644 --- a/OpenRA.Game/FileSystem/MixFile.cs +++ b/OpenRA.Game/FileSystem/MixFile.cs @@ -21,17 +21,16 @@ namespace OpenRA.FileSystem public sealed class MixFile : IReadOnlyPackage { public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } readonly Dictionary index; readonly long dataStart; readonly Stream s; - readonly int priority; readonly FileSystem context; - public MixFile(FileSystem context, string filename, int priority) + public MixFile(FileSystem context, string filename) { Name = filename; - this.priority = priority; this.context = context; s = context.Open(filename); @@ -194,7 +193,7 @@ namespace OpenRA.FileSystem return new SegmentStream(File.OpenRead(path), offset, entry.Length); } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { PackageEntry e; if (!index.TryGetValue(filename, out e)) @@ -203,18 +202,11 @@ namespace OpenRA.FileSystem return GetContent(e); } - public IEnumerable AllFileNames() - { - return index.Keys; - } - - public bool Exists(string filename) + public bool Contains(string filename) { return index.ContainsKey(filename); } - public int Priority { get { return 1000 + priority; } } - public void Dispose() { s.Dispose(); diff --git a/OpenRA.Game/FileSystem/Pak.cs b/OpenRA.Game/FileSystem/Pak.cs index 6ac57a7ae4..960bbc7471 100644 --- a/OpenRA.Game/FileSystem/Pak.cs +++ b/OpenRA.Game/FileSystem/Pak.cs @@ -22,15 +22,15 @@ namespace OpenRA.FileSystem public sealed class PakFile : IReadOnlyPackage { - readonly string filename; - readonly int priority; + public string Name { get; private set; } + public IEnumerable Contents { get { return index.Keys; } } + readonly Dictionary index; readonly Stream stream; - public PakFile(FileSystem context, string filename, int priority) + public PakFile(FileSystem context, string filename) { - this.filename = filename; - this.priority = priority; + Name = filename; index = new Dictionary(); stream = context.Open(filename); @@ -59,7 +59,7 @@ namespace OpenRA.FileSystem } } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { Entry entry; if (!index.TryGetValue(filename, out entry)) @@ -70,20 +70,11 @@ namespace OpenRA.FileSystem return new MemoryStream(data); } - public IEnumerable AllFileNames() - { - foreach (var filename in index.Keys) - yield return filename; - } - - public bool Exists(string filename) + public bool Contains(string filename) { return index.ContainsKey(filename); } - public int Priority { get { return 1000 + priority; } } - public string Name { get { return filename; } } - public void Dispose() { stream.Dispose(); diff --git a/OpenRA.Game/FileSystem/ZipFile.cs b/OpenRA.Game/FileSystem/ZipFile.cs index 03e25ce0f5..e20f94d657 100644 --- a/OpenRA.Game/FileSystem/ZipFile.cs +++ b/OpenRA.Game/FileSystem/ZipFile.cs @@ -18,8 +18,7 @@ namespace OpenRA.FileSystem { public sealed class ZipFile : IReadWritePackage { - readonly string filename; - readonly int priority; + public string Name { get; private set; } SZipFile pkg; static ZipFile() @@ -27,10 +26,9 @@ namespace OpenRA.FileSystem ZipConstants.DefaultCodePage = Encoding.UTF8.CodePage; } - public ZipFile(FileSystem context, string filename, int priority) + public ZipFile(FileSystem context, string filename) { - this.filename = filename; - this.priority = priority; + Name = filename; try { @@ -44,10 +42,9 @@ namespace OpenRA.FileSystem } // Create a new zip with the specified contents. - public ZipFile(FileSystem context, string filename, int priority, Dictionary contents) + public ZipFile(FileSystem context, string filename, Dictionary contents) { - this.priority = priority; - this.filename = filename; + Name = filename; if (File.Exists(filename)) File.Delete(filename); @@ -56,7 +53,7 @@ namespace OpenRA.FileSystem Write(contents); } - public Stream GetContent(string filename) + public Stream GetStream(string filename) { var entry = pkg.GetEntry(filename); if (entry == null) @@ -71,25 +68,25 @@ namespace OpenRA.FileSystem } } - public IEnumerable AllFileNames() + public IEnumerable Contents { - foreach (ZipEntry entry in pkg) - yield return entry.Name; + get + { + foreach (ZipEntry entry in pkg) + yield return entry.Name; + } } - public bool Exists(string filename) + public bool Contains(string filename) { return pkg.GetEntry(filename) != null; } - public int Priority { get { return 500 + priority; } } - public string Name { get { return filename; } } - public void Write(Dictionary contents) { // TODO: Clear existing content? pkg.Close(); - pkg = SZipFile.Create(filename); + pkg = SZipFile.Create(Name); pkg.BeginUpdate(); foreach (var kvp in contents) @@ -97,7 +94,7 @@ namespace OpenRA.FileSystem pkg.CommitUpdate(); pkg.Close(); - pkg = new SZipFile(new MemoryStream(File.ReadAllBytes(filename))); + pkg = new SZipFile(new MemoryStream(File.ReadAllBytes(Name))); } public void Dispose() diff --git a/OpenRA.Game/Manifest.cs b/OpenRA.Game/Manifest.cs index 4867766598..0342c92f84 100644 --- a/OpenRA.Game/Manifest.cs +++ b/OpenRA.Game/Manifest.cs @@ -36,7 +36,7 @@ namespace OpenRA public readonly ModMetadata Mod; public readonly string[] - Packages, Folders, Rules, ServerTraits, + Packages, Rules, ServerTraits, Sequences, VoxelSequences, Cursors, Chrome, Assemblies, ChromeLayout, Weapons, Voices, Notifications, Music, Translations, TileSets, ChromeMetrics, MapCompatibility, Missions; @@ -72,7 +72,6 @@ namespace OpenRA Mod.Id = modId; // TODO: Use fieldloader - Folders = YamlList(yaml, "Folders", true); MapFolders = YamlDictionary(yaml, "MapFolders", true); Packages = YamlList(yaml, "Packages", true); Rules = YamlList(yaml, "Rules", true); diff --git a/OpenRA.Game/Map/Map.cs b/OpenRA.Game/Map/Map.cs index 230c794bf4..35418c3c17 100644 --- a/OpenRA.Game/Map/Map.cs +++ b/OpenRA.Game/Map/Map.cs @@ -263,7 +263,7 @@ namespace OpenRA void AssertExists(string filename) { - using (var s = Container.GetContent(filename)) + using (var s = Container.GetStream(filename)) if (s == null) throw new InvalidOperationException("Required file {0} not present in this map".F(filename)); } @@ -316,12 +316,12 @@ namespace OpenRA public Map(string path) { Path = path; - Container = Game.ModData.ModFiles.OpenWritablePackage(path, int.MaxValue); + Container = Game.ModData.ModFiles.OpenWritablePackage(path); AssertExists("map.yaml"); AssertExists("map.bin"); - var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetContent("map.yaml"), path)); + var yaml = new MiniYaml(null, MiniYaml.FromStream(Container.GetStream("map.yaml"), path)); FieldLoader.Load(this, yaml); // Support for formats 1-3 dropped 2011-02-11. @@ -427,8 +427,8 @@ namespace OpenRA LastSubCell = (SubCell)(SubCellOffsets.Length - 1); DefaultSubCell = (SubCell)Grid.SubCellDefaultIndex; - if (Container.Exists("map.png")) - using (var dataStream = Container.GetContent("map.png")) + if (Container.Contains("map.png")) + using (var dataStream = Container.GetStream("map.png")) CustomPreview = new Bitmap(dataStream); PostInit(); @@ -634,12 +634,12 @@ namespace OpenRA // Add any custom assets if (Container != null) { - foreach (var file in Container.AllFileNames()) + foreach (var file in Container.Contents) { if (file == "map.bin" || file == "map.yaml") continue; - entries.Add(file, Container.GetContent(file).ReadAllBytes()); + entries.Add(file, Container.GetStream(file).ReadAllBytes()); } } @@ -649,7 +649,7 @@ namespace OpenRA Path = toPath; // Create a new map package - Container = Game.ModData.ModFiles.CreatePackage(Path, int.MaxValue, entries); + Container = Game.ModData.ModFiles.CreatePackage(Path, entries); } // Update existing package @@ -662,7 +662,7 @@ namespace OpenRA public CellLayer LoadMapTiles() { var tiles = new CellLayer(this); - using (var s = Container.GetContent("map.bin")) + using (var s = Container.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.TilesOffset > 0) @@ -694,7 +694,7 @@ namespace OpenRA public CellLayer LoadMapHeight() { var tiles = new CellLayer(this); - using (var s = Container.GetContent("map.bin")) + using (var s = Container.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.HeightsOffset > 0) @@ -716,7 +716,7 @@ namespace OpenRA { var resources = new CellLayer(this); - using (var s = Container.GetContent("map.bin")) + using (var s = Container.GetStream("map.bin")) { var header = new BinaryDataHeader(s, MapSize); if (header.ResourcesOffset > 0) @@ -968,9 +968,9 @@ namespace OpenRA using (var ms = new MemoryStream()) { // Read the relevant data into the buffer - using (var s = Container.GetContent("map.yaml")) + using (var s = Container.GetStream("map.yaml")) s.CopyTo(ms); - using (var s = Container.GetContent("map.bin")) + using (var s = Container.GetStream("map.bin")) s.CopyTo(ms); // Take the SHA1 diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index fd792d3467..66cb3254fe 100644 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -175,8 +175,8 @@ namespace OpenRA InitializeLoaders(); ModFiles.LoadFromManifest(Manifest); - // Mount map package so custom assets can be used. TODO: check priority. - ModFiles.Mount(ModFiles.OpenPackage(map.Path, int.MaxValue)); + // Mount map package so custom assets can be used. + ModFiles.Mount(ModFiles.OpenPackage(map.Path)); using (new Support.PerfTimer("Map.PreloadRules")) map.PreloadRules(); diff --git a/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs b/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs index 181fe1523d..3a3286cde2 100644 --- a/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs +++ b/OpenRA.Mods.Common/UtilityCommands/GenerateMinimapCommand.cs @@ -27,12 +27,9 @@ namespace OpenRA.Mods.Common.UtilityCommands public void Run(ModData modData, string[] args) { Game.ModData = modData; + modData.MountFiles(); + var map = new Map(args[1]); - - modData.ModFiles.UnmountAll(); - foreach (var dir in Game.ModData.Manifest.Folders) - modData.ModFiles.Mount(dir); - var minimap = Minimap.RenderMapPreview(map.Rules.TileSets[map.Tileset], map, true); var dest = Path.GetFileNameWithoutExtension(args[1]) + ".png"; diff --git a/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs index 8de9d08930..1ee5cc5cc5 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/AssetBrowserLogic.cs @@ -361,7 +361,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic if (assetSource == null) return; - var files = assetSource.AllFileNames().OrderBy(s => s); + var files = assetSource.Contents.OrderBy(s => s); foreach (var file in files) { if (allowedExtensions.Any(ext => file.EndsWith(ext, true, CultureInfo.InvariantCulture))) diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 0cc5dca850..28eb0efd39 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -7,21 +7,10 @@ Metadata: RequiresMods: modchooser: {DEV_VERSION} -Folders: +Packages: + ~^Content/cnc . ./mods/cnc - ./mods/cnc/bits - ./mods/cnc/bits/jungle - ./mods/cnc/bits/desert - ./mods/cnc/bits/ss - ./mods/cnc/uibits - ~^Content/cnc - -MapFolders: - ./mods/cnc/maps@System - ~^maps/cnc@User - -Packages: speech.mix conquer.mix sounds.mix @@ -29,13 +18,22 @@ Packages: temperat.mix winter.mix desert.mix - snow.mix ~movies-gdi.mix ~movies-nod.mix ~movies.mix ~scores.mix ~scores2.mix ~transit.mix + ./mods/cnc/bits/snow.mix + ./mods/cnc/bits + ./mods/cnc/bits/jungle + ./mods/cnc/bits/desert + ./mods/cnc/bits/ss + ./mods/cnc/uibits + +MapFolders: + ./mods/cnc/maps@System + ~^maps/cnc@User Rules: ./mods/cnc/rules/misc.yaml diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index ba2d98b399..71e61e6fb7 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -7,25 +7,23 @@ Metadata: RequiresMods: modchooser: {DEV_VERSION} -Folders: - . - d2k: - d2k:bits - d2k:bits/tex - d2k:bits/xmas - d2k:uibits +Packages: ~^Content/d2k ~^Content/d2k/GAMESFX ~^Content/d2k/Movies ~^Content/d2k/Music + . + d2k: + SOUND.RS + d2k:bits + d2k:bits/tex + d2k:bits/xmas + d2k:uibits MapFolders: d2k:maps@System ~^maps/d2k@User -Packages: - SOUND.RS - Rules: d2k:rules/misc.yaml d2k:rules/ai.yaml diff --git a/mods/modchooser/mod.yaml b/mods/modchooser/mod.yaml index 2b55eebe03..2b6dfa7b22 100644 --- a/mods/modchooser/mod.yaml +++ b/mods/modchooser/mod.yaml @@ -6,7 +6,7 @@ Metadata: RequiresMods: -Folders: +Packages: . ./mods/modchooser diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 3c7d40232b..368f4995ce 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -7,19 +7,10 @@ Metadata: RequiresMods: modchooser: {DEV_VERSION} -Folders: +Packages: + ~^Content/ra . ./mods/ra - ./mods/ra/bits - ./mods/ra/bits/desert - ./mods/ra/uibits - ~^Content/ra - -MapFolders: - ./mods/ra/maps@System - ~^maps/ra@User - -Packages: ~main.mix redalert.mix conquer.mix @@ -35,6 +26,13 @@ Packages: ~scores.mix ~movies1.mix ~movies2.mix + ./mods/ra/bits + ./mods/ra/bits/desert + ./mods/ra/uibits + +MapFolders: + ./mods/ra/maps@System + ~^maps/ra@User Rules: ./mods/ra/rules/misc.yaml diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 42b0257bf3..b2782587f2 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -7,18 +7,10 @@ Metadata: RequiresMods: modchooser: {DEV_VERSION} -Folders: +Packages: + ~^Content/ts . ./mods/ts - ./mods/ts/bits - ./mods/ts/uibits - ~^Content/ts - -MapFolders: - ./mods/ts/maps@System - ~^maps/ts@User - -Packages: # Tiberian Sun ~scores.mix ~sidenc01.mix @@ -58,6 +50,12 @@ Packages: ~e01vox01.mix ~e01vox02.mix ~ecache01.mix + ./mods/ts/bits + ./mods/ts/uibits + +MapFolders: + ./mods/ts/maps@System + ~^maps/ts@User Rules: ./mods/ts/rules/ai.yaml