public Stream OpenDataFile(IndexEntry entry) { var archive = CASCConfig.Archives[entry.Index]; string file = Program.Settings.RemoteHostPath + "/data/" + archive.Substring(0, 2) + "/" + archive.Substring(2, 2) + "/" + archive; string url = string.Format("http://{0}/{1}", Program.Settings.RemoteHost, file); Stream stream = Cache.OpenFile(file, url, true); if (stream != null) { stream.Position = entry.Offset; MemoryStream ms = new MemoryStream(entry.Size); stream.CopyBytes(ms, entry.Size); ms.Position = 0; return ms; } HttpWebRequest req = (HttpWebRequest) WebRequest.Create(url); req.AddRange(entry.Offset, entry.Offset + entry.Size - 1); using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) { MemoryStream ms = new MemoryStream(entry.Size); resp.GetResponseStream().CopyBytes(ms, entry.Size); ms.Position = 0; return ms; } }
private void ParseIndex(Stream stream, int i) { using (var br = new BinaryReader(stream)) { stream.Seek(-12, SeekOrigin.End); int count = br.ReadInt32(); stream.Seek(0, SeekOrigin.Begin); if (count * (16 + 4 + 4) > stream.Length) throw new Exception("ParseIndex failed"); for (int j = 0; j < count; ++j) { MD5Hash key = br.Read<MD5Hash>(); if (key.IsZeroed()) // wtf? key = br.Read<MD5Hash>(); if (key.IsZeroed()) // wtf? throw new Exception("key.IsZeroed()"); IndexEntry entry = new IndexEntry(); entry.Index = i; entry.Size = br.ReadInt32BE(); entry.Offset = br.ReadInt32BE(); CDNIndexData.Add(key, entry); } } }
private Stream OpenFileOnlineInternal(IndexEntry entry, MD5Hash hash) { Stream stream = entry != null ? CDNIndex.OpenDataFile(entry) : CDNIndex.OpenDataFileDirect(hash); return new BLTEStream(stream, hash); }
private Stream GetLocalDataStreamInternal(IndexEntry idxInfo, MD5Hash key) { if (idxInfo == null) throw new Exception("Missing local index."); Stream dataStream = GetDataStream(idxInfo.Index); dataStream.Position = idxInfo.Offset; using (BinaryReader reader = new BinaryReader(dataStream, System.Text.Encoding.ASCII, true)) { byte[] md5 = reader.ReadBytes(16); Array.Reverse(md5); if (!key.EqualsTo(md5)) throw new Exception("local data corrupted"); int size = reader.ReadInt32(); if (size != idxInfo.Size) throw new Exception("local data corrupted"); //byte[] unkData1 = reader.ReadBytes(2); //byte[] unkData2 = reader.ReadBytes(8); dataStream.Position += 10; byte[] data = reader.ReadBytes(idxInfo.Size - 30); return new MemoryStream(data); } }
private void ParseIndex(string idx) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); MD5Hash key = br.Read<MD5Hash>(); byte indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); info.Size = br.ReadInt32(); if (!LocalIndexData.ContainsKey(key)) LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; } }