Distinguish between classic and crc file hashes. Fixes #3306, #3328.

This commit is contained in:
Paul Chote
2013-05-24 20:15:36 +12:00
parent d9fab238d5
commit 0dd8d7f7b6
10 changed files with 148 additions and 102 deletions

View File

@@ -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;
}