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