Пример #1
0
        public IEnumerable <string> AllFileNames()
        {
            var lookup = new Dictionary <uint, string>();

            if (Exists("local mix database.dat"))
            {
                var db = new XccLocalDatabase(GetContent("local mix database.dat"));
                foreach (var e in db.Entries)
                {
                    var hash = PackageEntry.HashFilename(e, type);
                    if (!lookup.ContainsKey(hash))
                    {
                        lookup.Add(hash, e);
                    }
                }
            }

            if (GlobalFileSystem.Exists("global mix database.dat"))
            {
                var db = new XccGlobalDatabase(GlobalFileSystem.Open("global mix database.dat"));
                foreach (var e in db.Entries)
                {
                    var hash = PackageEntry.HashFilename(e, type);
                    if (!lookup.ContainsKey(hash))
                    {
                        lookup.Add(hash, e);
                    }
                }
            }

            return(index.Keys.Select(k => lookup.ContainsKey(k) ? lookup[k] : "{0:X}".F(k)));
        }
Пример #2
0
        public D2kSoundResources(string filename, int priority)
        {
            this.filename = filename;
            this.priority = priority;

            s = GlobalFileSystem.Open(filename);
            s.Seek(0, SeekOrigin.Begin);

            filenames = new List <string>();

            var headerLength = s.ReadUInt32();

            while (s.Position < headerLength + 4)
            {
                var name   = s.ReadASCIIZ();
                var offset = s.ReadUInt32();
                var length = s.ReadUInt32();

                var hash = PackageEntry.HashFilename(name, PackageHashType.Classic);
                if (!index.ContainsKey(hash))
                {
                    index.Add(hash, new PackageEntry(hash, offset, length));
                }

                filenames.Add(name);
            }
        }
Пример #3
0
        public D2kSoundResources(FileSystem context, string filename, int priority)
        {
            this.filename = filename;
            this.priority = priority;

            s = context.Open(filename);
            try
            {
                filenames = new List <string>();

                var headerLength = s.ReadUInt32();
                while (s.Position < headerLength + 4)
                {
                    var name   = s.ReadASCIIZ();
                    var offset = s.ReadUInt32();
                    var length = s.ReadUInt32();

                    var hash = PackageEntry.HashFilename(name, PackageHashType.Classic);
                    if (!index.ContainsKey(hash))
                    {
                        index.Add(hash, new PackageEntry(hash, offset, length));
                    }

                    filenames.Add(name);
                }
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Пример #4
0
 public IEnumerable <uint> ClassicHashes()
 {
     foreach (var filename in index.Keys)
     {
         yield return(PackageEntry.HashFilename(filename, PackageHashType.Classic));
     }
 }
Пример #5
0
 public IEnumerable <uint> ClassicHashes()
 {
     foreach (ZipEntry entry in pkg)
     {
         yield return(PackageEntry.HashFilename(entry.Name, PackageHashType.Classic));
     }
 }
Пример #6
0
 public IEnumerable <uint> ClassicHashes()
 {
     foreach (var filename in Directory.GetFiles(path, "*", SearchOption.TopDirectoryOnly))
     {
         yield return(PackageEntry.HashFilename(Path.GetFileName(filename), PackageHashType.Classic));
     }
 }
Пример #7
0
        public Stream GetContent(PackageEntry entry)
        {
            Stream parentStream;
            var    offset = dataStart + entry.Offset + SegmentStream.GetOverallNestedOffset(s, out parentStream);
            var    path   = ((FileStream)parentStream).Name;

            return(new SegmentStream(File.OpenRead(path), offset, entry.Length));
        }
Пример #8
0
            Dictionary <string, PackageEntry> ParseIndex(Dictionary <uint, PackageEntry> entries, HashSet <string> allPossibleFilenames)
            {
                var classicIndex = new Dictionary <string, PackageEntry>();
                var crcIndex     = new Dictionary <string, PackageEntry>();

                // 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)
                    {
                        using (var content = GetContent(kv.Value))
                        {
                            var db = new XccLocalDatabase(content);
                            foreach (var e in db.Entries)
                            {
                                allPossibleFilenames.Add(e);
                            }
                        }

                        break;
                    }
                }

                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);
            }
Пример #9
0
        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);
        }
Пример #10
0
        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);
                }
            }
        }
Пример #11
0
            public Stream GetContent(PackageEntry entry)
            {
                Stream parentStream;
                var    baseOffset   = dataStart + entry.Offset;
                var    nestedOffset = baseOffset + SegmentStream.GetOverallNestedOffset(s, out parentStream);

                // Special case FileStream - instead of creating an in-memory copy,
                // just reference the portion of the on-disk file that we need to save memory.
                // We use GetType instead of 'is' here since we can't handle any derived classes of FileStream.
                if (parentStream.GetType() == typeof(FileStream))
                {
                    var path = ((FileStream)parentStream).Name;
                    return(new SegmentStream(File.OpenRead(path), nestedOffset, entry.Length));
                }

                // For all other streams, create a copy in memory.
                // This uses more memory but is the only way in general to ensure the returned streams won't clash.
                s.Seek(baseOffset, SeekOrigin.Begin);
                return(new MemoryStream(s.ReadBytes((int)entry.Length)));
            }
Пример #12
0
        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 bool Exists(string filename)
 {
     return(index.ContainsKey(PackageEntry.HashFilename(filename, PackageHashType.Classic)));
 }
Пример #15
0
 public IEnumerable <uint> ClassicHashes()
 {
     return(entries.Keys.Select(filename => PackageEntry.HashFilename(filename, PackageHashType.Classic)));
 }
 public Stream GetContent(string filename)
 {
     return(GetContent(PackageEntry.HashFilename(filename, PackageHashType.Classic)));
 }
Пример #17
0
 public IEnumerable <uint> ClassicHashes()
 {
     return(fileLookup.Keys.Select(k => PackageEntry.HashFilename(k, PackageHashType.Classic)));
 }
Пример #18
0
 public static uint HashFilename(string name, PackageHashType type)
 {
     return(PackageEntry.HashFilename(name, type));
 }