Example #1
0
        public static void GetIndexes(string url, MD5Hash[] archives)
        {
            Parallel.ForEach(archives, (archive, state, i) =>
            {
                uint indexID;
                string indexName = archive.ToHexString().ToLower();

                try
                {
                    cacheLock.EnterUpgradeableReadLock();

                    if (!CASC.indexNames.Contains(archives[i], new MD5HashComparer()))
                    {
                        try
                        {
                            cacheLock.EnterWriteLock();
                            CASC.indexNames.Add(archive);
                            indexID = (uint)CASC.indexNames.Count - 1;
                        }
                        finally
                        {
                            cacheLock.ExitWriteLock();
                        }
                    }
                    else
                    {
                        return;
                    }
                }
                finally
                {
                    cacheLock.ExitUpgradeableReadLock();
                }


                byte[] indexContent;

                if (url.StartsWith("http"))
                {
                    indexContent = CDN.Get(url + "data/" + indexName[0] + indexName[1] + "/" + indexName[2] + indexName[3] + "/" + indexName + ".index");
                }
                else
                {
                    indexContent = File.ReadAllBytes(Path.Combine(url, "data", "" + indexName[0] + indexName[1], "" + indexName[2] + indexName[3], indexName + ".index"));
                }

                using (BinaryReader bin = new BinaryReader(new MemoryStream(indexContent)))
                {
                    bin.BaseStream.Position = bin.BaseStream.Length - 12;
                    var entryCount          = bin.ReadUInt32();
                    bin.BaseStream.Position = 0;

                    int indexEntries = indexContent.Length / 4096;

                    var entriesRead = 0;
                    for (var b = 0; b < indexEntries; b++)
                    {
                        for (var bi = 0; bi < 170; bi++)
                        {
                            var headerHash = bin.Read <MD5Hash>();

                            var entry = new IndexEntry()
                            {
                                indexID = indexID,
                                size    = bin.ReadUInt32(true),
                                offset  = bin.ReadUInt32(true)
                            };

                            entriesRead++;

                            cacheLock.EnterUpgradeableReadLock();
                            try
                            {
                                if (!CASC.indexDictionary.ContainsKey(headerHash))
                                {
                                    cacheLock.EnterWriteLock();
                                    try
                                    {
                                        CASC.indexDictionary.Add(headerHash, entry);
                                    }
                                    finally
                                    {
                                        cacheLock.ExitWriteLock();
                                    }
                                }
                            }
                            finally
                            {
                                cacheLock.ExitUpgradeableReadLock();
                            }
                        }

                        if (entriesRead == entryCount)
                        {
                            return;
                        }

                        // 16 bytes padding that rounds the chunk to 4096 bytes (index entry is 24 bytes, 24 * 170 = 4080 bytes so 16 bytes remain)
                        bin.ReadBytes(16);
                    }
                }
            });
        }