Add a context argument to package files contructors

This commit is contained in:
Pavel Penev
2015-11-21 02:59:00 +02:00
parent 4ce1444c6b
commit d08a400565
12 changed files with 59 additions and 49 deletions

View File

@@ -27,11 +27,13 @@ namespace OpenRA.FileSystem
readonly Stream s; readonly Stream s;
readonly int bagFilePriority; readonly int bagFilePriority;
readonly Dictionary<uint, IdxEntry> index; readonly Dictionary<uint, IdxEntry> index;
readonly FileSystem context;
public BagFile(string filename, int priority) public BagFile(FileSystem context, string filename, int priority)
{ {
bagFilename = filename; bagFilename = filename;
bagFilePriority = priority; bagFilePriority = priority;
this.context = context;
// 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
@@ -39,14 +41,14 @@ namespace OpenRA.FileSystem
// Build the index and dispose the stream, it is no longer needed after this // Build the index and dispose the stream, it is no longer needed after this
List<IdxEntry> entries; List<IdxEntry> entries;
using (var indexStream = Game.ModData.ModFiles.Open(indexFilename)) using (var indexStream = context.Open(indexFilename))
entries = new IdxReader(indexStream).Entries; entries = new IdxReader(indexStream).Entries;
index = entries.ToDictionaryWithConflictLog(x => x.Hash, index = entries.ToDictionaryWithConflictLog(x => x.Hash,
"{0} (bag format)".F(filename), "{0} (bag format)".F(filename),
null, x => "(offs={0}, len={1})".F(x.Offset, x.Length)); null, x => "(offs={0}, len={1})".F(x.Offset, x.Length));
s = Game.ModData.ModFiles.Open(filename); s = context.Open(filename);
} }
public int Priority { get { return 1000 + bagFilePriority; } } public int Priority { get { return 1000 + bagFilePriority; } }
@@ -159,9 +161,9 @@ namespace OpenRA.FileSystem
public IEnumerable<string> AllFileNames() public IEnumerable<string> AllFileNames()
{ {
var lookup = new Dictionary<uint, string>(); var lookup = new Dictionary<uint, string>();
if (Game.ModData.ModFiles.Exists("global mix database.dat")) if (context.Exists("global mix database.dat"))
{ {
var db = new XccGlobalDatabase(Game.ModData.ModFiles.Open("global mix database.dat")); var db = new XccGlobalDatabase(context.Open("global mix database.dat"));
foreach (var e in db.Entries) foreach (var e in db.Entries)
{ {
var hash = IdxEntry.HashFilename(e, PackageHashType.CRC32); var hash = IdxEntry.HashFilename(e, PackageHashType.CRC32);
@@ -175,7 +177,7 @@ namespace OpenRA.FileSystem
public void Write(Dictionary<string, byte[]> contents) public void Write(Dictionary<string, byte[]> contents)
{ {
Game.ModData.ModFiles.Unmount(this); context.Unmount(this);
throw new NotImplementedException("Updating bag files unsupported"); throw new NotImplementedException("Updating bag files unsupported");
} }

View File

@@ -22,12 +22,12 @@ namespace OpenRA.FileSystem
readonly Dictionary<string, Entry> entries = new Dictionary<string, Entry>(); readonly Dictionary<string, Entry> entries = new Dictionary<string, Entry>();
readonly Stream s; readonly Stream s;
public BigFile(string filename, int priority) public BigFile(FileSystem context, string filename, int priority)
{ {
Name = filename; Name = filename;
Priority = priority; Priority = priority;
s = Game.ModData.ModFiles.Open(filename); s = context.Open(filename);
try try
{ {
if (s.ReadASCII(4) != "BIGF") if (s.ReadASCII(4) != "BIGF")

View File

@@ -24,12 +24,12 @@ namespace OpenRA.FileSystem
readonly Dictionary<uint, PackageEntry> index = new Dictionary<uint, PackageEntry>(); readonly Dictionary<uint, PackageEntry> index = new Dictionary<uint, PackageEntry>();
public D2kSoundResources(string filename, int priority) public D2kSoundResources(FileSystem context, string filename, int priority)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
s = Game.ModData.ModFiles.Open(filename); s = context.Open(filename);
try try
{ {
filenames = new List<string>(); filenames = new List<string>();

View File

@@ -28,14 +28,14 @@ namespace OpenRA.FileSystem
Cache<uint, List<IFolder>> crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>()); Cache<uint, List<IFolder>> crcHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
Cache<uint, List<IFolder>> classicHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>()); Cache<uint, List<IFolder>> classicHashIndex = new Cache<uint, List<IFolder>>(_ => new List<IFolder>());
public static IFolder CreatePackage(string filename, int order, Dictionary<string, byte[]> content) public IFolder CreatePackage(string filename, int order, Dictionary<string, byte[]> content)
{ {
if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase))
return new MixFile(filename, order, content); return new MixFile(this, filename, order, content);
if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(filename, order, content); return new ZipFile(this, filename, order, content);
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(filename, order, content); return new ZipFile(this, filename, order, content);
if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase))
throw new NotImplementedException("The creation of .RS archives is unimplemented"); throw new NotImplementedException("The creation of .RS archives is unimplemented");
if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
@@ -50,7 +50,7 @@ namespace OpenRA.FileSystem
return new Folder(filename, order, content); return new Folder(filename, order, content);
} }
public static IFolder OpenPackage(string filename, string annotation, int order) public IFolder OpenPackage(string filename, string annotation, int order)
{ {
if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase))
{ {
@@ -58,25 +58,25 @@ namespace OpenRA.FileSystem
? PackageHashType.Classic ? PackageHashType.Classic
: FieldLoader.GetValue<PackageHashType>("(value)", annotation); : FieldLoader.GetValue<PackageHashType>("(value)", annotation);
return new MixFile(filename, type, order); return new MixFile(this, filename, type, order);
} }
if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(filename, order); return new ZipFile(this, filename, order);
if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".oramap", StringComparison.InvariantCultureIgnoreCase))
return new ZipFile(filename, order); return new ZipFile(this, filename, order);
if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".RS", StringComparison.InvariantCultureIgnoreCase))
return new D2kSoundResources(filename, order); return new D2kSoundResources(this, filename, order);
if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".Z", StringComparison.InvariantCultureIgnoreCase))
return new InstallShieldPackage(filename, order); return new InstallShieldPackage(this, filename, order);
if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".PAK", StringComparison.InvariantCultureIgnoreCase))
return new PakFile(filename, order); return new PakFile(this, filename, order);
if (filename.EndsWith(".big", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".big", StringComparison.InvariantCultureIgnoreCase))
return new BigFile(filename, order); return new BigFile(this, filename, order);
if (filename.EndsWith(".bag", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".bag", StringComparison.InvariantCultureIgnoreCase))
return new BagFile(filename, order); return new BagFile(this, filename, order);
if (filename.EndsWith(".hdr", StringComparison.InvariantCultureIgnoreCase)) if (filename.EndsWith(".hdr", StringComparison.InvariantCultureIgnoreCase))
return new InstallShieldCABExtractor(filename, order); return new InstallShieldCABExtractor(this, filename, order);
return new Folder(filename, order); return new Folder(filename, order);
} }

View File

@@ -186,6 +186,7 @@ namespace OpenRA.FileSystem
class CabReader : IDisposable class CabReader : IDisposable
{ {
readonly FileSystem context;
readonly FileDescriptor fileDes; readonly FileDescriptor fileDes;
public uint RemainingArchiveStream; public uint RemainingArchiveStream;
public uint RemainingFileStream; public uint RemainingFileStream;
@@ -194,11 +195,12 @@ namespace OpenRA.FileSystem
ushort volumeNumber; ushort volumeNumber;
Stream cabFile; Stream cabFile;
public CabReader(FileDescriptor fileDes, uint index, string commonName) public CabReader(FileSystem context, FileDescriptor fileDes, uint index, string commonName)
{ {
this.fileDes = fileDes; this.fileDes = fileDes;
this.index = index; this.index = index;
this.commonName = commonName; this.commonName = commonName;
this.context = context;
volumeNumber = (ushort)((uint)fileDes.Volume - 1u); volumeNumber = (ushort)((uint)fileDes.Volume - 1u);
RemainingArchiveStream = 0; RemainingArchiveStream = 0;
if ((fileDes.Flags & FileCompressed) > 0) if ((fileDes.Flags & FileCompressed) > 0)
@@ -207,7 +209,7 @@ namespace OpenRA.FileSystem
RemainingFileStream = fileDes.ExpandedSize; RemainingFileStream = fileDes.ExpandedSize;
cabFile = null; cabFile = null;
NextFile(); NextFile(context);
} }
public void CopyTo(Stream dest) public void CopyTo(Stream dest)
@@ -257,7 +259,7 @@ namespace OpenRA.FileSystem
var read = cabFile.Read(outArray, 0, (int)RemainingArchiveStream); var read = cabFile.Read(outArray, 0, (int)RemainingArchiveStream);
if (RemainingFileStream > RemainingArchiveStream) if (RemainingFileStream > RemainingArchiveStream)
{ {
NextFile(); NextFile(context);
RemainingArchiveStream -= (uint)cabFile.Read(outArray, read, (int)count - read); RemainingArchiveStream -= (uint)cabFile.Read(outArray, read, (int)count - read);
} }
@@ -270,13 +272,13 @@ namespace OpenRA.FileSystem
cabFile.Dispose(); cabFile.Dispose();
} }
public void NextFile() void NextFile(FileSystem context)
{ {
if (cabFile != null) if (cabFile != null)
cabFile.Dispose(); cabFile.Dispose();
++volumeNumber; ++volumeNumber;
cabFile = Game.ModData.ModFiles.Open("{0}{1}.cab".F(commonName, volumeNumber)); cabFile = context.Open("{0}{1}.cab".F(commonName, volumeNumber));
if (cabFile.ReadUInt32() != 0x28635349) if (cabFile.ReadUInt32() != 0x28635349)
throw new InvalidDataException("Not an Installshield CAB package"); throw new InvalidDataException("Not an Installshield CAB package");
@@ -328,19 +330,21 @@ namespace OpenRA.FileSystem
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> fileLookup = new Dictionary<string, uint>();
readonly FileSystem context;
int priority; int priority;
string commonName; string commonName;
public int Priority { get { return priority; } } public int Priority { get { return priority; } }
public string Name { get { return commonName; } } public string Name { get { return commonName; } }
public InstallShieldCABExtractor(string hdrFilename, int priority = -1) public InstallShieldCABExtractor(FileSystem context, string hdrFilename, int priority = -1)
{ {
var fileGroups = new List<FileGroup>(); var fileGroups = new List<FileGroup>();
var fileGroupOffsets = new List<uint>(); var fileGroupOffsets = new List<uint>();
hdrFile = context.Open(hdrFilename);
this.priority = priority; this.priority = priority;
hdrFile = Game.ModData.ModFiles.Open(hdrFilename); this.context = context;
// Strips archive number AND file extension // Strips archive number AND file extension
commonName = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", ""); commonName = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", "");
@@ -471,7 +475,7 @@ namespace OpenRA.FileSystem
var output = new MemoryStream((int)fileDes.ExpandedSize); var output = new MemoryStream((int)fileDes.ExpandedSize);
using (var reader = new CabReader(fileDes, index, commonName)) using (var reader = new CabReader(context, fileDes, index, commonName))
reader.CopyTo(output); reader.CopyTo(output);
if (output.Length != fileDes.ExpandedSize) if (output.Length != fileDes.ExpandedSize)
@@ -496,7 +500,7 @@ 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(fileDes, index, commonName)) using (var reader = new CabReader(context, fileDes, index, commonName))
reader.CopyTo(output); reader.CopyTo(output);
if (output.Length != fileDes.ExpandedSize) if (output.Length != fileDes.ExpandedSize)

View File

@@ -24,14 +24,14 @@ namespace OpenRA.FileSystem
readonly int priority; readonly int priority;
readonly string filename; readonly string filename;
public InstallShieldPackage(string filename, int priority) public InstallShieldPackage(FileSystem context, string filename, int priority)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
filenames = new List<string>(); filenames = new List<string>();
s = Game.ModData.ModFiles.Open(filename); s = context.Open(filename);
try try
{ {
// Parse package header // Parse package header

View File

@@ -25,14 +25,16 @@ namespace OpenRA.FileSystem
readonly Stream s; readonly Stream s;
readonly int priority; readonly int priority;
readonly string filename; readonly string filename;
readonly FileSystem context;
readonly PackageHashType type; readonly PackageHashType type;
// Save a mix to disk with the given contents // Save a mix to disk with the given contents
public MixFile(string filename, int priority, Dictionary<string, byte[]> contents) public MixFile(FileSystem context, string filename, int priority, Dictionary<string, byte[]> contents)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
this.type = PackageHashType.Classic; this.type = PackageHashType.Classic;
this.context = context;
if (File.Exists(filename)) if (File.Exists(filename))
File.Delete(filename); File.Delete(filename);
@@ -51,13 +53,14 @@ namespace OpenRA.FileSystem
} }
} }
public MixFile(string filename, PackageHashType type, int priority) public MixFile(FileSystem context, string filename, PackageHashType type, int priority)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
this.type = type; this.type = type;
this.context = context;
s = Game.ModData.ModFiles.Open(filename); s = context.Open(filename);
try try
{ {
// Detect format type // Detect format type
@@ -223,9 +226,9 @@ namespace OpenRA.FileSystem
} }
} }
if (Game.ModData.ModFiles.Exists("global mix database.dat")) if (context.Exists("global mix database.dat"))
{ {
var db = new XccGlobalDatabase(Game.ModData.ModFiles.Open("global mix database.dat")); var db = new XccGlobalDatabase(context.Open("global mix database.dat"));
foreach (var e in db.Entries) foreach (var e in db.Entries)
{ {
var hash = PackageEntry.HashFilename(e, type); var hash = PackageEntry.HashFilename(e, type);
@@ -249,7 +252,7 @@ namespace OpenRA.FileSystem
{ {
// Cannot modify existing mixfile - rename existing file and // Cannot modify existing mixfile - rename existing file and
// create a new one with original content plus modifications // create a new one with original content plus modifications
Game.ModData.ModFiles.Unmount(this); context.Unmount(this);
// TODO: Add existing data to the contents list // TODO: Add existing data to the contents list
if (index.Count > 0) if (index.Count > 0)

View File

@@ -28,13 +28,13 @@ namespace OpenRA.FileSystem
readonly Dictionary<string, Entry> index; readonly Dictionary<string, Entry> index;
readonly Stream stream; readonly Stream stream;
public PakFile(string filename, int priority) public PakFile(FileSystem context, string filename, int priority)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
index = new Dictionary<string, Entry>(); index = new Dictionary<string, Entry>();
stream = Game.ModData.ModFiles.Open(filename); stream = context.Open(filename);
try try
{ {
index = new Dictionary<string, Entry>(); index = new Dictionary<string, Entry>();

View File

@@ -28,10 +28,11 @@ namespace OpenRA.FileSystem
ZipConstants.DefaultCodePage = Encoding.Default.CodePage; ZipConstants.DefaultCodePage = Encoding.Default.CodePage;
} }
public ZipFile(string filename, int priority) public ZipFile(FileSystem context, string filename, int priority)
{ {
this.filename = filename; this.filename = filename;
this.priority = priority; this.priority = priority;
try try
{ {
// Pull the file into memory, don't keep it open. // Pull the file into memory, don't keep it open.
@@ -44,7 +45,7 @@ namespace OpenRA.FileSystem
} }
// Create a new zip with the specified contents. // Create a new zip with the specified contents.
public ZipFile(string filename, int priority, Dictionary<string, byte[]> contents) public ZipFile(FileSystem context, string filename, int priority, Dictionary<string, byte[]> contents)
{ {
this.priority = priority; this.priority = priority;
this.filename = filename; this.filename = filename;

View File

@@ -317,7 +317,7 @@ namespace OpenRA
public Map(string path) public Map(string path)
{ {
Path = path; Path = path;
Container = FileSystem.FileSystem.OpenPackage(path, null, int.MaxValue); Container = Game.ModData.ModFiles.OpenPackage(path, null, int.MaxValue);
AssertExists("map.yaml"); AssertExists("map.yaml");
AssertExists("map.bin"); AssertExists("map.bin");
@@ -650,7 +650,7 @@ namespace OpenRA
Path = toPath; Path = toPath;
// Create a new map package // Create a new map package
Container = FileSystem.FileSystem.CreatePackage(Path, int.MaxValue, entries); Container = Game.ModData.ModFiles.CreatePackage(Path, int.MaxValue, entries);
} }
// Update existing package // Update existing package

View File

@@ -170,7 +170,7 @@ namespace OpenRA
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. TODO: check priority.
ModFiles.Mount(FS.OpenPackage(map.Path, null, int.MaxValue)); ModFiles.Mount(ModFiles.OpenPackage(map.Path, null, int.MaxValue));
using (new Support.PerfTimer("Map.PreloadRules")) using (new Support.PerfTimer("Map.PreloadRules"))
map.PreloadRules(); map.PreloadRules();

View File

@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
new Thread(() => new Thread(() =>
{ {
using (var cabExtractor = new InstallShieldCABExtractor(source)) using (var cabExtractor = new InstallShieldCABExtractor(Game.ModData.ModFiles, source))
{ {
var denom = installData.InstallShieldCABFileIds.Count; var denom = installData.InstallShieldCABFileIds.Count;
var extractFiles = installData.ExtractFilesFromCD; var extractFiles = installData.ExtractFilesFromCD;