@@ -19,8 +19,8 @@ namespace OpenRA.FileFormats
|
||||
public static class FileSystem
|
||||
{
|
||||
public static List<IFolder> MountedFolders = new List<IFolder>();
|
||||
|
||||
static Cache<uint, List<IFolder>> allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
static Cache<uint, List<IFolder>> classicHashIndex = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
static Cache<uint, List<IFolder>> crcHashIndex = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
|
||||
public static List<string> FolderPaths = new List<string>();
|
||||
|
||||
@@ -28,9 +28,16 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
MountedFolders.Add(folder);
|
||||
|
||||
foreach (var hash in folder.AllFileHashes())
|
||||
foreach (var hash in folder.ClassicHashes())
|
||||
{
|
||||
var l = allFiles[hash];
|
||||
var l = classicHashIndex[hash];
|
||||
if (!l.Contains(folder))
|
||||
l.Add(folder);
|
||||
}
|
||||
|
||||
foreach (var hash in folder.CrcHashes())
|
||||
{
|
||||
var l = crcHashIndex[hash];
|
||||
if (!l.Contains(folder))
|
||||
l.Add(folder);
|
||||
}
|
||||
@@ -38,11 +45,6 @@ namespace OpenRA.FileFormats
|
||||
|
||||
static int order = 0;
|
||||
|
||||
static IFolder OpenPackage(string filename)
|
||||
{
|
||||
return OpenPackage(filename, order++);
|
||||
}
|
||||
|
||||
public static IFolder CreatePackage(string filename, int order, Dictionary<string, byte[]> content)
|
||||
{
|
||||
if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase))
|
||||
@@ -57,10 +59,14 @@ namespace OpenRA.FileFormats
|
||||
return new Folder(filename, order, content);
|
||||
}
|
||||
|
||||
public static IFolder OpenPackage(string filename, int order)
|
||||
public static IFolder OpenPackage(string filename, string annotation, int order)
|
||||
{
|
||||
if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase))
|
||||
return new MixFile(filename, order);
|
||||
{
|
||||
var type = string.IsNullOrEmpty(annotation) ? PackageHashType.Classic :
|
||||
FieldLoader.GetValue<PackageHashType>("(value)", annotation);
|
||||
return new MixFile(filename, type, order);
|
||||
}
|
||||
else if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
|
||||
return new ZipFile(filename, order);
|
||||
else if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
|
||||
@@ -72,6 +78,11 @@ namespace OpenRA.FileFormats
|
||||
}
|
||||
|
||||
public static void Mount(string name)
|
||||
{
|
||||
Mount(name, null);
|
||||
}
|
||||
|
||||
public static void Mount(string name, string annotation)
|
||||
{
|
||||
var optional = name.StartsWith("~");
|
||||
if (optional) name = name.Substring(1);
|
||||
@@ -81,7 +92,7 @@ namespace OpenRA.FileFormats
|
||||
name = Platform.SupportDir+name.Substring(1);
|
||||
|
||||
FolderPaths.Add(name);
|
||||
Action a = () => FileSystem.MountInner(OpenPackage(name));
|
||||
Action a = () => FileSystem.MountInner(OpenPackage(name, annotation, order++));
|
||||
|
||||
if (optional)
|
||||
try { a(); }
|
||||
@@ -94,7 +105,8 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
MountedFolders.Clear();
|
||||
FolderPaths.Clear();
|
||||
allFiles = new Cache<uint, List<IFolder>>( _ => new List<IFolder>() );
|
||||
classicHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
|
||||
crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
|
||||
}
|
||||
|
||||
public static bool Unmount(IFolder mount)
|
||||
@@ -110,13 +122,17 @@ namespace OpenRA.FileFormats
|
||||
public static void LoadFromManifest(Manifest manifest)
|
||||
{
|
||||
UnmountAll();
|
||||
foreach (var dir in manifest.Folders) Mount(dir);
|
||||
foreach (var pkg in manifest.Packages) Mount(pkg);
|
||||
foreach (var dir in manifest.Folders)
|
||||
Mount(dir);
|
||||
|
||||
foreach (var pkg in manifest.Packages)
|
||||
Mount(pkg.Key, pkg.Value);
|
||||
}
|
||||
|
||||
static Stream GetFromCache(Cache<uint, List<IFolder>> index, string filename)
|
||||
static Stream GetFromCache(PackageHashType type, string filename)
|
||||
{
|
||||
var folder = index[PackageEntry.HashFilename(filename)]
|
||||
var index = type == PackageHashType.CRC32 ? crcHashIndex : classicHashIndex;
|
||||
var folder = index[PackageEntry.HashFilename(filename, type)]
|
||||
.Where(x => x.Exists(filename))
|
||||
.OrderBy(x => x.Priority)
|
||||
.FirstOrDefault();
|
||||
@@ -131,11 +147,15 @@ namespace OpenRA.FileFormats
|
||||
|
||||
public static Stream OpenWithExts(string filename, params string[] exts)
|
||||
{
|
||||
if( filename.IndexOfAny( new char[] { '/', '\\' } ) == -1 )
|
||||
if (filename.IndexOfAny(new char[] { '/', '\\' } ) == -1)
|
||||
{
|
||||
foreach( var ext in exts )
|
||||
foreach (var ext in exts)
|
||||
{
|
||||
var s = GetFromCache(allFiles, filename + ext);
|
||||
var s = GetFromCache(PackageHashType.Classic, filename + ext);
|
||||
if (s != null)
|
||||
return s;
|
||||
|
||||
s = GetFromCache(PackageHashType.CRC32, filename + ext);
|
||||
if (s != null)
|
||||
return s;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user