diff --git a/OpenRA.FileFormats/Filesystem/FileSystem.cs b/OpenRA.FileFormats/Filesystem/FileSystem.cs index 81ae616ca2..91b7c851f0 100644 --- a/OpenRA.FileFormats/Filesystem/FileSystem.cs +++ b/OpenRA.FileFormats/Filesystem/FileSystem.cs @@ -41,6 +41,20 @@ namespace OpenRA.FileFormats return OpenPackage(filename, order++); } + public static IFolder CreatePackage(string filename, int order, Dictionary content) + { + if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) + return new MixFile(filename, order, content); + else if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) + return new ZipFile(filename, order, content); + else if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) + return new ZipFile(filename, order, content); + else if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) + throw new NotImplementedException("Creating .Z archives is unsupported"); + else + return new Folder(filename, order, content); + } + public static IFolder OpenPackage(string filename, int order) { if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) diff --git a/OpenRA.FileFormats/Filesystem/Folder.cs b/OpenRA.FileFormats/Filesystem/Folder.cs index 68fc3b41a0..e389edd2cb 100644 --- a/OpenRA.FileFormats/Filesystem/Folder.cs +++ b/OpenRA.FileFormats/Filesystem/Folder.cs @@ -20,7 +20,22 @@ namespace OpenRA.FileFormats int priority; - public Folder(string path, int priority) { this.path = path; this.priority = priority; } + // Create a new folder package + public Folder(string path, int priority, Dictionary contents) + { + this.path = path; + this.priority = priority; + if (Directory.Exists(path)) + Directory.Delete(path); + + Write(contents); + } + + public Folder(string path, int priority) + { + this.path = path; + this.priority = priority; + } public Stream GetContent(string filename) { diff --git a/OpenRA.FileFormats/Filesystem/MixFile.cs b/OpenRA.FileFormats/Filesystem/MixFile.cs index de1f5e49d1..093d824a12 100644 --- a/OpenRA.FileFormats/Filesystem/MixFile.cs +++ b/OpenRA.FileFormats/Filesystem/MixFile.cs @@ -31,6 +31,17 @@ namespace OpenRA.FileFormats readonly long dataStart; readonly Stream s; int priority; + + // Create a new MixFile + public MixFile(string filename, int priority, Dictionary contents) + { + this.priority = priority; + if (File.Exists(filename)) + File.Delete(filename); + + s = File.Create(filename); + Write(contents); + } public MixFile(string filename, int priority) { @@ -162,6 +173,14 @@ namespace OpenRA.FileFormats public void Write(Dictionary contents) { + // Cannot modify existing mixfile - rename existing file and + // create a new one with original content plus modifications + FileSystem.Unmount(this); + + // TODO: Add existing data to the contents list + if (index.Count > 0) + throw new NotImplementedException("Updating mix files unfinished"); + // Construct a list of entries for the file header uint dataSize = 0; var items = new List(); @@ -173,6 +192,8 @@ namespace OpenRA.FileFormats dataSize += length; } + // Write the new file + s.Seek(0,SeekOrigin.Begin); using (var writer = new BinaryWriter(s)) { // Write file header diff --git a/OpenRA.FileFormats/Filesystem/ZipFile.cs b/OpenRA.FileFormats/Filesystem/ZipFile.cs index d4c13938ad..d7830ecd40 100644 --- a/OpenRA.FileFormats/Filesystem/ZipFile.cs +++ b/OpenRA.FileFormats/Filesystem/ZipFile.cs @@ -23,19 +23,25 @@ namespace OpenRA.FileFormats public ZipFile(string filename, int priority) { this.priority = priority; - if (File.Exists(filename)) + try { - try - { - pkg = new SZipFile(File.OpenRead(filename)); - } - catch (ZipException e) - { - Log.Write("debug", "Couldn't load zip file: {0}", e.Message); - } + pkg = new SZipFile(File.OpenRead(filename)); } - else - pkg = SZipFile.Create(filename); + catch (ZipException e) + { + Log.Write("debug", "Couldn't load zip file: {0}", e.Message); + } + } + + // Create a new zip with the specified contents + public ZipFile(string filename, int priority, Dictionary contents) + { + this.priority = priority; + if (File.Exists(filename)) + File.Delete(filename); + + pkg = SZipFile.Create(filename); + Write(contents); } public Stream GetContent(string filename) diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index f19be4927f..67dfba2d20 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -55,24 +55,23 @@ namespace OpenRA public static Map FromTileset(string tileset) { - Map map = new Map(); - map.MapSize = new int2(1, 1); - map.Tileset = tileset; - map.MapResources = new TileReference[1, 1]; - - var tile = OpenRA.Rules.TileSets[map.Tileset].Templates.First(); - map.MapTiles = new TileReference[1, 1] + var tile = OpenRA.Rules.TileSets[tileset].Templates.First(); + Map map = new Map() + { + Title = "Name your map here", + Description = "Describe your map here", + Author = "Your name here", + MapSize = new int2(1, 1), + PlayerCount = 0, + Tileset = tileset, + MapResources = new TileReference[1, 1], + MapTiles = new TileReference[1, 1] { { new TileReference { type = tile.Key, image = (byte)(tile.Value.PickAny ? 0xffu : 0), - index = (byte)(tile.Value.PickAny ? 0xffu : 0) } } }; - - map.PlayerCount = 0; - map.ResizeCordon(0,0,0,0); - - map.Title = "Name your map here"; - map.Description = "Describe your map here"; - map.Author = "Your name here"; + index = (byte)(tile.Value.PickAny ? 0xffu : 0) } + } }, + }; return map; } @@ -195,17 +194,7 @@ namespace OpenRA } public void Save(string toPath) - { - // Saving the map to a new location - if (toPath != Path) - { - // TODO: Copy all other files (resources, rules) in the map package - Path = toPath; - - // TODO: This doesn't work - need a FileSystem.CreatePackage() - Container = FileSystem.OpenPackage(Path, int.MaxValue); - } - + { // Todo: save to a zip file in the support dir by default MapFormat = 3; @@ -238,6 +227,18 @@ namespace OpenRA entries.Add("map.bin", SaveBinaryData()); var s = root.WriteToString(); entries.Add("map.yaml", System.Text.Encoding.UTF8.GetBytes(s)); + + // Saving the map to a new location + if (toPath != Path) + { + Path = toPath; + + // Create a new map package + // TODO: Add other files (resources, rules) to the entries list + Container = FileSystem.CreatePackage(Path, int.MaxValue, entries); + } + + // Update existing package Container.Write(entries); }