static Stream GetFromCache(PackageHashType type, string filename) { var index = type == PackageHashType.CRC32 ? crcHashIndex : classicHashIndex; var folder = index[PackageEntry.HashFilename(filename, type)] .Where(x => x.Exists(filename)) .MinByOrDefault(x => x.Priority); if (folder != null) { return(folder.GetContent(filename)); } return(null); }
public void Write(Dictionary <string, byte[]> contents) { // Cannot modify existing mixfile - rename existing file and // create a new one with original content plus modifications GlobalFileSystem.Unmount(this); // TODO: Add existing data to the contents list if (index.Count > 0) { throw new NotImplementedException("Updating mix files unfinished"); } // Construct a list of entries for the file header uint dataSize = 0; var items = new List <PackageEntry>(); foreach (var kv in contents) { var length = (uint)kv.Value.Length; var hash = PackageEntry.HashFilename(Path.GetFileName(kv.Key), type); items.Add(new PackageEntry(hash, dataSize, length)); dataSize += length; } // Write the new file s.Seek(0, SeekOrigin.Begin); using (var writer = new BinaryWriter(s)) { // Write file header writer.Write((ushort)items.Count); writer.Write(dataSize); foreach (var item in items) { item.Write(writer); } writer.Flush(); // Copy file data foreach (var file in contents) { s.Write(file.Value); } } }
uint?FindMatchingHash(string filename) { var hash = PackageEntry.HashFilename(filename, type); if (index.ContainsKey(hash)) { return(hash); } // Maybe we were given a raw hash? uint raw; if (!uint.TryParse(filename, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out raw)) { return(null); } if ("{0:X}".F(raw) == filename && index.ContainsKey(raw)) { return(raw); } return(null); }
void ParseFile(BinaryReader reader) { reader.ReadBytes(7); var CompressedSize = reader.ReadUInt32(); reader.ReadBytes(12); var ChunkSize = reader.ReadUInt16(); reader.ReadBytes(4); var NameLength = reader.ReadByte(); var FileName = new String(reader.ReadChars(NameLength)); var hash = PackageEntry.HashFilename(FileName, PackageHashType.Classic); if (!index.ContainsKey(hash)) { index.Add(hash, new PackageEntry(hash, AccumulatedData, CompressedSize)); } filenames.Add(FileName); AccumulatedData += CompressedSize; // Skip to the end of the chunk reader.ReadBytes(ChunkSize - NameLength - 30); }
public IEnumerable <uint> ClassicHashes() { return(fileLookup.Keys.Select(k => PackageEntry.HashFilename(k, PackageHashType.Classic))); }
Dictionary <string, PackageEntry> ParseIndex(Dictionary <uint, PackageEntry> entries) { var classicIndex = new Dictionary <string, PackageEntry>(); var crcIndex = new Dictionary <string, PackageEntry>(); var allPossibleFilenames = new HashSet <string>(); // Try and find a local mix database var dbNameClassic = PackageEntry.HashFilename("local mix database.dat", PackageHashType.Classic); var dbNameCRC = PackageEntry.HashFilename("local mix database.dat", PackageHashType.CRC32); foreach (var kv in entries) { if (kv.Key == dbNameClassic || kv.Key == dbNameCRC) { var db = new XccLocalDatabase(GetContent(kv.Value)); foreach (var e in db.Entries) { allPossibleFilenames.Add(e); } break; } } // Load the global mix database // TODO: This should be passed to the mix file ctor if (context.Exists("global mix database.dat")) { using (var db = new XccGlobalDatabase(context.Open("global mix database.dat"))) { foreach (var e in db.Entries) { allPossibleFilenames.Add(e); } } } foreach (var filename in allPossibleFilenames) { var classicHash = PackageEntry.HashFilename(filename, PackageHashType.Classic); var crcHash = PackageEntry.HashFilename(filename, PackageHashType.CRC32); PackageEntry e; if (entries.TryGetValue(classicHash, out e)) { classicIndex.Add(filename, e); } if (entries.TryGetValue(crcHash, out e)) { crcIndex.Add(filename, e); } } var bestIndex = crcIndex.Count > classicIndex.Count ? crcIndex : classicIndex; var unknown = entries.Count - bestIndex.Count; if (unknown > 0) { Log.Write("debug", "{0}: failed to resolve filenames for {1} unknown hashes".F(Name, unknown)); } return(bestIndex); }
public bool Exists(string filename) { return(index.ContainsKey(PackageEntry.HashFilename(filename, PackageHashType.Classic))); }
public Stream GetContent(string filename) { return(GetContent(PackageEntry.HashFilename(filename, PackageHashType.Classic))); }
public IEnumerable <uint> ClassicHashes() { return(entries.Keys.Select(filename => PackageEntry.HashFilename(filename, PackageHashType.Classic))); }
public static uint HashFilename(string name, PackageHashType type) { return(PackageEntry.HashFilename(name, type)); }