Exemplo n.º 1
0
        public Wc3RootHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"root\"...");

            using (StreamReader sr = new StreamReader(stream.BaseStream))
            {
                string line;

                while ((line = sr.ReadLine()) != null)
                {
                    string[] tokens = line.Split('|');

                    if (tokens.Length != 3 && tokens.Length != 4)
                    {
                        throw new InvalidDataException("tokens.Length != 3 && tokens.Length != 4");
                    }

                    string file;

                    if (tokens[0].IndexOf(':') != -1)
                    {
                        string[] tokens2 = tokens[0].Split(':');

                        if (tokens2.Length == 2 || tokens2.Length == 3 || tokens2.Length == 4)
                        {
                            file = Path.Combine(tokens2);
                        }
                        else
                        {
                            throw new InvalidDataException("tokens2.Length");
                        }
                    }
                    else
                    {
                        file = tokens[0];
                    }

                    if (!Enum.TryParse(tokens[2], out LocaleFlags locale))
                    {
                        locale = LocaleFlags.All;
                    }

                    ulong fileHash = Hasher.ComputeHash(file);

                    RootData[fileHash] = new RootEntry()
                    {
                        LocaleFlags  = locale,
                        ContentFlags = ContentFlags.None,
                        cKey         = tokens[1].FromHexString().ToMD5()
                    };

                    CASCFile.Files[fileHash] = new CASCFile(fileHash, file);
                }
            }

            worker?.ReportProgress(100);
        }
Exemplo n.º 2
0
        private void AddFile(string pkg, D3RootEntry e)
        {
            string name;

            switch (e.Type)
            {
            case 0:
                SNOInfo sno1 = tocParser.GetSNO(e.SNO);
                name = string.Format("{0}\\{1}{2}", sno1.GroupId, sno1.Name, sno1.Ext);
                break;

            case 1:
                SNOInfo sno2 = tocParser.GetSNO(e.SNO);
                name = string.Format("{0}\\{1}\\{2:D4}", sno2.GroupId, sno2.Name, e.FileIndex);

                string ext = pkgParser.GetExtension(name);

                if (ext != null)
                {
                    name += ext;
                }
                else
                {
                    CountUnknown++;
                    name += ".xxx";
                }
                break;

            case 2:
                name = e.Name;
                break;

            default:
                name = "Unknown";
                break;
            }

            RootEntry entry = new RootEntry
            {
                MD5 = e.MD5
            };

            if (Enum.TryParse(pkg, out LocaleFlags locale))
            {
                entry.LocaleFlags = locale;
            }
            else
            {
                entry.LocaleFlags = LocaleFlags.All;
            }

            ulong fileHash = Hasher.ComputeHash(name);

            CASCFile.Files[fileHash] = new CASCFile(fileHash, name);

            RootData.Add(fileHash, entry);
        }
Exemplo n.º 3
0
        public S1RootHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"root\"...");

            using (StreamReader sr = new StreamReader(stream.BaseStream))
            {
                string line;

                while ((line = sr.ReadLine()) != null)
                {
                    string[] tokens = line.Split('|');

                    string file;

                    LocaleFlags locale = LocaleFlags.All;

                    if (tokens[0].IndexOf(':') != -1)
                    {
                        string[] tokens2 = tokens[0].Split(':');

                        file   = tokens2[0];
                        locale = (LocaleFlags)Enum.Parse(typeof(LocaleFlags), tokens2[1]);
                    }
                    else
                    {
                        file = tokens[0];
                    }

                    ulong fileHash = Hasher.ComputeHash(file);

                    RootData[fileHash] = new RootEntry()
                    {
                        LocaleFlags  = locale,
                        ContentFlags = ContentFlags.None,
                        MD5          = tokens[1].ToByteArray().ToMD5()
                    };

                    CASCFile.Files[fileHash] = new CASCFile(fileHash, file);
                }
            }

            worker?.ReportProgress(100);
        }
Exemplo n.º 4
0
        public WowRootHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"root\"...");

            int magic = stream.ReadInt32();

            int numFilesTotal = 0, numFilesWithNameHash = 0, numFilesRead = 0;

            const int TSFMMagic = 0x4D465354;

            if (magic == TSFMMagic)
            {
                numFilesTotal        = stream.ReadInt32();
                numFilesWithNameHash = stream.ReadInt32();
            }
            else
            {
                stream.BaseStream.Position -= 4;
            }

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                int count = stream.ReadInt32();

                numFilesRead += count;

                ContentFlags contentFlags = (ContentFlags)stream.ReadUInt32();
                LocaleFlags  localeFlags  = (LocaleFlags)stream.ReadUInt32();

                if (localeFlags == LocaleFlags.None)
                {
                    throw new InvalidDataException("block.LocaleFlags == LocaleFlags.None");
                }

                if (contentFlags != ContentFlags.None && (contentFlags & (ContentFlags.F00000001 | ContentFlags.Windows | ContentFlags.MacOS | ContentFlags.Alternate | ContentFlags.F00020000 | ContentFlags.F00080000 | ContentFlags.F00100000 | ContentFlags.F00200000 | ContentFlags.F00400000 | ContentFlags.F02000000 | ContentFlags.NotCompressed | ContentFlags.NoNameHash | ContentFlags.F20000000)) == 0)
                {
                    throw new InvalidDataException("block.ContentFlags != ContentFlags.None");
                }

                RootEntry[] entries     = new RootEntry[count];
                int[]       filedataIds = new int[count];

                int fileDataIndex = 0;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].LocaleFlags  = localeFlags;
                    entries[i].ContentFlags = contentFlags;

                    filedataIds[i] = fileDataIndex + stream.ReadInt32();
                    fileDataIndex  = filedataIds[i] + 1;
                }

                //Console.WriteLine("Block: {0} {1} (size {2})", block.ContentFlags, block.LocaleFlags, count);

                ulong[] nameHashes = null;

                if (magic == TSFMMagic)
                {
                    for (var i = 0; i < count; ++i)
                    {
                        entries[i].cKey = stream.Read <MD5Hash>();
                    }

                    if ((contentFlags & ContentFlags.NoNameHash) == 0)
                    {
                        nameHashes = new ulong[count];

                        for (var i = 0; i < count; ++i)
                        {
                            nameHashes[i] = stream.ReadUInt64();
                        }
                    }
                }
                else
                {
                    nameHashes = new ulong[count];

                    for (var i = 0; i < count; ++i)
                    {
                        entries[i].cKey = stream.Read <MD5Hash>();
                        nameHashes[i]   = stream.ReadUInt64();
                    }
                }

                for (var i = 0; i < count; ++i)
                {
                    int fileDataId = filedataIds[i];

                    //Logger.WriteLine("filedataid {0}", fileDataId);

                    ulong hash;

                    if (nameHashes == null)
                    {
                        hash = FileDataHash.ComputeHash(fileDataId);
                    }
                    else
                    {
                        hash = nameHashes[i];
                    }

                    RootData.Add(fileDataId, entries[i]);

                    //Console.WriteLine("File: {0:X8} {1:X16} {2}", entries[i].FileDataId, hash, entries[i].MD5.ToHexString());

                    if (FileDataStore.TryGetValue(fileDataId, out ulong hash2))
                    {
                        if (hash2 == hash)
                        {
                            // duplicate, skipping
                        }
                        else
                        {
                            Logger.WriteLine("ERROR: got miltiple hashes for filedataid {0}", fileDataId);
                        }
                        continue;
                    }

                    FileDataStore.Add(fileDataId, hash);
                    FileDataStoreReverse.Add(hash, fileDataId);

                    if (nameHashes != null)
                    {
                        // generate our custom hash as well so we can still find file without calling GetHashByFileDataId in some weird cases
                        ulong fileDataHash = FileDataHash.ComputeHash(fileDataId);
                        FileDataStoreReverse.Add(fileDataHash, fileDataId);
                    }
                }

                worker?.ReportProgress((int)(stream.BaseStream.Position / (float)stream.BaseStream.Length * 100));
            }
        }
Exemplo n.º 5
0
        public WowRootHandler(BinaryReader stream, BackgroundWorker worker)
        {
            worker?.ReportProgress(0, "Loading root...");

            int numFilesRead = 0;

            var magic                = stream.ReadInt32();
            var numFilesTotal        = stream.ReadInt32();
            var numFilesWithNameHash = stream.ReadInt32();

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                int count = stream.ReadInt32();

                numFilesRead += count;

                ContentFlags contentFlags = (ContentFlags)stream.ReadUInt32();
                LocaleFlags  localeFlags  = (LocaleFlags)stream.ReadUInt32();

                if (localeFlags == LocaleFlags.None)
                {
                    throw new Exception("block.LocaleFlags == LocaleFlags.None");
                }

                if (contentFlags != ContentFlags.None && (contentFlags & (ContentFlags.F00000001 | ContentFlags.Windows | ContentFlags.MacOS | ContentFlags.Alternate | ContentFlags.F00020000 | ContentFlags.F00080000 | ContentFlags.F00100000 | ContentFlags.F00400000 | ContentFlags.F02000000 | ContentFlags.NotCompressed | ContentFlags.NoNameHash | ContentFlags.F20000000)) == 0)
                {
                    throw new Exception("block.ContentFlags != ContentFlags.None");
                }

                RootEntry[] entries     = new RootEntry[count];
                int[]       filedataIds = new int[count];

                int fileDataIndex = 0;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].LocaleFlags  = localeFlags;
                    entries[i].ContentFlags = contentFlags;

                    filedataIds[i] = fileDataIndex + stream.ReadInt32();
                    fileDataIndex  = filedataIds[i] + 1;
                }

                //Debug.Log("Block: {0} {1} (size {2})", block.ContentFlags, block.LocaleFlags, count);

                ulong[] nameHashes = null;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].MD5 = stream.Read <MD5Hash>();
                }

                if (numFilesRead > numFilesTotal - numFilesWithNameHash)
                {
                    nameHashes = new ulong[count];

                    for (var i = 0; i < count; ++i)
                    {
                        nameHashes[i] = stream.ReadUInt64();
                    }
                }

                //for (var i = 0; i < count; ++i)
                Parallel.For(0, count, i =>
                {
                    var fileDataId = filedataIds[i];
                    var hash       = 0UL;

                    if (nameHashes == null)
                    {
                        hash = FileDataHash.ComputeHash(fileDataId);
                    }
                    else
                    {
                        hash = nameHashes[i];
                    }

                    RootData.Add(fileDataId, entries[i]);
                    FileDataStore.TryAdd(fileDataId, hash);
                    FileDataStoreReverse.TryAdd(hash, fileDataId);

                    // if (nameHashes != null)
                    // {
                    //     // generate our custom hash as well so we can still find file without calling GetHashByFileDataId in some weird cases
                    //     var fileDataHash = FileDataHash.ComputeHash(fileDataId);
                    //     FileDataStoreReverse.TryAdd(fileDataHash, fileDataId);
                    // }
                });

                worker?.ReportProgress((int)(stream.BaseStream.Position / (float)stream.BaseStream.Length * 100), "Loading root...");
            }
        }
Exemplo n.º 6
0
        public WowRootHandler(BinaryReader stream, BackgroundWorkerEx worker)
        {
            worker?.ReportProgress(0, "Loading \"root\"...");

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                int count = stream.ReadInt32();

                ContentFlags contentFlags = (ContentFlags)stream.ReadUInt32();
                LocaleFlags  localeFlags  = (LocaleFlags)stream.ReadUInt32();

                if (localeFlags == LocaleFlags.None)
                {
                    throw new Exception("block.LocaleFlags == LocaleFlags.None");
                }

                if (contentFlags != ContentFlags.None && (contentFlags & (ContentFlags.F00000008 | ContentFlags.F00000010 | ContentFlags.LowViolence | ContentFlags.NoCompression | ContentFlags.F20000000)) == 0)
                {
                    throw new Exception("block.ContentFlags != ContentFlags.None");
                }

                RootEntry[] entries     = new RootEntry[count];
                int[]       filedataIds = new int[count];

                int fileDataIndex = 0;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].LocaleFlags  = localeFlags;
                    entries[i].ContentFlags = contentFlags;

                    filedataIds[i] = fileDataIndex + stream.ReadInt32();
                    fileDataIndex  = filedataIds[i] + 1;
                }

                //Console.WriteLine("Block: {0} {1} (size {2})", block.ContentFlags, block.LocaleFlags, count);

                for (var i = 0; i < count; ++i)
                {
                    entries[i].MD5 = stream.Read <MD5Hash>();

                    ulong hash = stream.ReadUInt64();

                    RootData.Add(hash, entries[i]);

                    //Console.WriteLine("File: {0:X8} {1:X16} {2}", entries[i].FileDataId, hash, entries[i].MD5.ToHexString());

                    int fileDataId = filedataIds[i];

                    if (FileDataStore.TryGetValue(fileDataId, out ulong hash2))
                    {
                        if (hash2 == hash)
                        {
                            // duplicate, skipping
                            continue;
                        }
                        else
                        {
                            Logger.WriteLine("ERROR: got miltiple hashes for filedataid {0}", fileDataId);
                            continue;
                        }
                    }

                    FileDataStore.Add(fileDataId, hash);
                    FileDataStoreReverse.Add(hash, fileDataId);
                }

                worker?.ReportProgress((int)(stream.BaseStream.Position / (float)stream.BaseStream.Length * 100));
            }
        }
Exemplo n.º 7
0
        public WowRootHandler(BinaryReader stream)
        {
            int numFilesRead = 0;

            var magic                = stream.ReadInt32();
            var numFilesTotal        = stream.ReadInt32();
            var numFilesWithNameHash = stream.ReadInt32();

            while (stream.BaseStream.Position < stream.BaseStream.Length)
            {
                int count = stream.ReadInt32();

                numFilesRead += count;

                ContentFlags contentFlags = (ContentFlags)stream.ReadUInt32();
                LocaleFlags  localeFlags  = (LocaleFlags)stream.ReadUInt32();

                if (localeFlags == LocaleFlags.None)
                {
                    throw new Exception("block.LocaleFlags == LocaleFlags.None");
                }

                if (contentFlags != ContentFlags.None && (contentFlags & (ContentFlags.F00000001 | ContentFlags.Windows | ContentFlags.MacOS | ContentFlags.Alternate | ContentFlags.F00020000 | ContentFlags.F00080000 | ContentFlags.F00100000 | ContentFlags.F00400000 | ContentFlags.F02000000 | ContentFlags.NotCompressed | ContentFlags.NoNameHash | ContentFlags.F20000000)) == 0)
                {
                    throw new Exception("block.ContentFlags != ContentFlags.None");
                }

                RootEntry[] entries     = new RootEntry[count];
                int[]       filedataIds = new int[count];

                int fileDataIndex = 0;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].LocaleFlags  = localeFlags;
                    entries[i].ContentFlags = contentFlags;

                    filedataIds[i] = fileDataIndex + stream.ReadInt32();
                    fileDataIndex  = filedataIds[i] + 1;
                }

                //Console.WriteLine("Block: {0} {1} (size {2})", block.ContentFlags, block.LocaleFlags, count);

                ulong[] nameHashes = null;

                for (var i = 0; i < count; ++i)
                {
                    entries[i].MD5 = stream.Read <MD5Hash>();
                }

                if (numFilesRead > numFilesTotal - numFilesWithNameHash)
                {
                    nameHashes = new ulong[count];

                    for (var i = 0; i < count; ++i)
                    {
                        nameHashes[i] = stream.ReadUInt64();
                    }
                }

                for (var i = 0; i < count; ++i)
                {
                    var fileDataId = filedataIds[i];
                    var hash       = 0UL;

                    if (nameHashes == null)
                    {
                        hash = FileDataHash.ComputeHash(fileDataId);
                    }
                    else
                    {
                        hash = nameHashes[i];
                    }

                    RootData.Add(fileDataId, entries[i]);
                    if (FileDataStore.TryGetValue(fileDataId, out ulong hash2))
                    {
                        if (hash2 != hash)
                        {
                            Console.WriteLine("ERROR: got multiple hashes for filedataid {0}", fileDataId);
                        }

                        continue;
                    }

                    FileDataStore.Add(fileDataId, hash);
                    FileDataStoreReverse.Add(hash, fileDataId);
                }
                ;
            }
        }