Add support for oramod packages.
This commit is contained in:
@@ -45,6 +45,8 @@ namespace OpenRA.FileSystem
|
|||||||
return new ZipFile(this, filename);
|
return new ZipFile(this, filename);
|
||||||
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
|
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
|
||||||
return new ZipFile(this, filename);
|
return new ZipFile(this, filename);
|
||||||
|
if (filename.EndsWith(".oramod", StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
return new ZipFile(this, filename);
|
||||||
if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase))
|
if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase))
|
||||||
return new D2kSoundResources(this, filename);
|
return new D2kSoundResources(this, filename);
|
||||||
if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
|
if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
|
||||||
@@ -61,8 +63,7 @@ namespace OpenRA.FileSystem
|
|||||||
IReadOnlyPackage parent;
|
IReadOnlyPackage parent;
|
||||||
string subPath = null;
|
string subPath = null;
|
||||||
if (TryGetPackageContaining(filename, out parent, out subPath))
|
if (TryGetPackageContaining(filename, out parent, out subPath))
|
||||||
if (parent is Folder)
|
return OpenPackage(subPath, parent);
|
||||||
return new Folder(Path.Combine(((Folder)parent).Name, subPath));
|
|
||||||
|
|
||||||
return new Folder(Platform.ResolvePath(filename));
|
return new Folder(Platform.ResolvePath(filename));
|
||||||
}
|
}
|
||||||
@@ -90,6 +91,15 @@ namespace OpenRA.FileSystem
|
|||||||
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
|
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
|
||||||
return new ZipFile(this, filename, parent.GetStream(filename));
|
return new ZipFile(this, filename, parent.GetStream(filename));
|
||||||
|
|
||||||
|
if (parent is ZipFile)
|
||||||
|
return new ZipFolder(this, (ZipFile)parent, filename, filename);
|
||||||
|
|
||||||
|
if (parent is ZipFolder)
|
||||||
|
{
|
||||||
|
var folder = (ZipFolder)parent;
|
||||||
|
return new ZipFolder(this, folder.Parent, folder.Name + "/" + filename, filename);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
75
OpenRA.Game/FileSystem/ZipFolder.cs
Normal file
75
OpenRA.Game/FileSystem/ZipFolder.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2015 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see COPYING.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
|
using SZipFile = ICSharpCode.SharpZipLib.Zip.ZipFile;
|
||||||
|
|
||||||
|
namespace OpenRA.FileSystem
|
||||||
|
{
|
||||||
|
public sealed class ZipFolder : IReadOnlyPackage
|
||||||
|
{
|
||||||
|
public string Name { get; private set; }
|
||||||
|
public ZipFile Parent { get; private set; }
|
||||||
|
readonly string path;
|
||||||
|
|
||||||
|
static ZipFolder()
|
||||||
|
{
|
||||||
|
ZipConstants.DefaultCodePage = Encoding.UTF8.CodePage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZipFolder(FileSystem context, ZipFile parent, string path, string filename)
|
||||||
|
{
|
||||||
|
if (filename.EndsWith("/"))
|
||||||
|
filename = filename.Substring(0, filename.Length - 1);
|
||||||
|
|
||||||
|
Name = filename;
|
||||||
|
Parent = parent;
|
||||||
|
if (path.EndsWith("/"))
|
||||||
|
path = path.Substring(0, path.Length - 1);
|
||||||
|
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream GetStream(string filename)
|
||||||
|
{
|
||||||
|
// Zip files use '/' as a path separator
|
||||||
|
return Parent.GetStream(path + '/' + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> Contents
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
foreach (var entry in Parent.Contents)
|
||||||
|
{
|
||||||
|
if (entry.StartsWith(path) && entry != path)
|
||||||
|
{
|
||||||
|
var filename = entry.Substring(path.Length + 1);
|
||||||
|
var dirLevels = filename.Split('/').Count(c => !string.IsNullOrEmpty(c));
|
||||||
|
if (dirLevels == 1)
|
||||||
|
yield return filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(string filename)
|
||||||
|
{
|
||||||
|
return Parent.Contains(path + '/' + filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() { /* nothing to do */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
@@ -40,10 +41,19 @@ namespace OpenRA
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
IReadOnlyPackage package = null;
|
IReadOnlyPackage package = null;
|
||||||
if (Directory.Exists(pair.Value))
|
if (Directory.Exists(pair.Second))
|
||||||
package = new Folder(pair.Value);
|
package = new Folder(pair.Second);
|
||||||
else
|
else
|
||||||
throw new InvalidDataException(pair.Value + " is not a valid mod package");
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
package = new ZipFile(null, pair.Second);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new InvalidDataException(pair.Second + " is not a valid mod package");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!package.Contains("mod.yaml"))
|
if (!package.Contains("mod.yaml"))
|
||||||
continue;
|
continue;
|
||||||
@@ -54,7 +64,7 @@ namespace OpenRA
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
var metadata = FieldLoader.Load<ModMetadata>(nd["Metadata"]);
|
var metadata = FieldLoader.Load<ModMetadata>(nd["Metadata"]);
|
||||||
metadata.Id = pair.Key;
|
metadata.Id = pair.First;
|
||||||
metadata.Package = package;
|
metadata.Package = package;
|
||||||
|
|
||||||
if (nd.ContainsKey("RequiresMods"))
|
if (nd.ContainsKey("RequiresMods"))
|
||||||
@@ -65,11 +75,13 @@ namespace OpenRA
|
|||||||
if (nd.ContainsKey("ContentInstaller"))
|
if (nd.ContainsKey("ContentInstaller"))
|
||||||
metadata.Content = FieldLoader.Load<ContentInstaller>(nd["ContentInstaller"]);
|
metadata.Content = FieldLoader.Load<ContentInstaller>(nd["ContentInstaller"]);
|
||||||
|
|
||||||
ret.Add(pair.Key, metadata);
|
// Mods in the support directory and oramod packages (which are listed later
|
||||||
|
// in the CandidateMods list) override mods in the main install.
|
||||||
|
ret[pair.First] = metadata;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine("An exception occurred when trying to load ModMetadata for `{0}`:".F(pair.Key));
|
Console.WriteLine("An exception occurred when trying to load ModMetadata for `{0}`:".F(pair.First));
|
||||||
Console.WriteLine(ex.Message);
|
Console.WriteLine(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,12 +89,16 @@ namespace OpenRA
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Dictionary<string, string> GetCandidateMods()
|
static IEnumerable<Pair<string, string>> GetCandidateMods()
|
||||||
{
|
{
|
||||||
// Get mods that are in the game folder.
|
// Get mods that are in the game folder.
|
||||||
var basePath = Platform.ResolvePath(Path.Combine(".", "mods"));
|
var basePath = Platform.ResolvePath(Path.Combine(".", "mods"));
|
||||||
var mods = Directory.GetDirectories(basePath)
|
var mods = Directory.GetDirectories(basePath)
|
||||||
.ToDictionary(x => x.Substring(basePath.Length + 1));
|
.Select(x => Pair.New(x.Substring(basePath.Length + 1), x))
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var m in Directory.GetFiles(basePath, "*.oramod"))
|
||||||
|
mods.Add(Pair.New(Path.GetFileNameWithoutExtension(m), m));
|
||||||
|
|
||||||
// Get mods that are in the support folder.
|
// Get mods that are in the support folder.
|
||||||
var supportPath = Platform.ResolvePath(Path.Combine("^", "mods"));
|
var supportPath = Platform.ResolvePath(Path.Combine("^", "mods"));
|
||||||
@@ -90,7 +106,10 @@ namespace OpenRA
|
|||||||
return mods;
|
return mods;
|
||||||
|
|
||||||
foreach (var pair in Directory.GetDirectories(supportPath).ToDictionary(x => x.Substring(supportPath.Length + 1)))
|
foreach (var pair in Directory.GetDirectories(supportPath).ToDictionary(x => x.Substring(supportPath.Length + 1)))
|
||||||
mods.Add(pair.Key, pair.Value);
|
mods.Add(Pair.New(pair.Key, pair.Value));
|
||||||
|
|
||||||
|
foreach (var m in Directory.GetFiles(supportPath, "*.oramod"))
|
||||||
|
mods.Add(Pair.New(Path.GetFileNameWithoutExtension(m), m));
|
||||||
|
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,6 +255,7 @@
|
|||||||
<Compile Include="Graphics\RgbaColorRenderer.cs" />
|
<Compile Include="Graphics\RgbaColorRenderer.cs" />
|
||||||
<Compile Include="Traits\Player\IndexedPlayerPalette.cs" />
|
<Compile Include="Traits\Player\IndexedPlayerPalette.cs" />
|
||||||
<Compile Include="Traits\ActivityUtils.cs" />
|
<Compile Include="Traits\ActivityUtils.cs" />
|
||||||
|
<Compile Include="FileSystem\ZipFolder.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="FileSystem\D2kSoundResources.cs" />
|
<Compile Include="FileSystem\D2kSoundResources.cs" />
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
directoryDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, writableDirectories, setupItem);
|
directoryDropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 210, writableDirectories, setupItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapIsUnpacked = map.Package != null && map.Package is Folder;
|
var mapIsUnpacked = map.Package != null && (map.Package is Folder || map.Package is ZipFolder);
|
||||||
|
|
||||||
var filename = widget.Get<TextFieldWidget>("FILENAME");
|
var filename = widget.Get<TextFieldWidget>("FILENAME");
|
||||||
filename.Text = map.Package == null ? "" : mapIsUnpacked ? Path.GetFileName(map.Package.Name) : Path.GetFileNameWithoutExtension(map.Package.Name);
|
filename.Text = map.Package == null ? "" : mapIsUnpacked ? Path.GetFileName(map.Package.Name) : Path.GetFileNameWithoutExtension(map.Package.Name);
|
||||||
|
|||||||
Reference in New Issue
Block a user