public static async Task <RootFile> GetRoot(string hash, bool parseIt = false) { var root = new RootFile { entriesLookup = new MultiDictionary <ulong, RootEntry>(), entriesFDID = new MultiDictionary <uint, RootEntry>(), }; byte[] content = await CDNCache.Get("data", hash); if (!parseIt) { return(root); } var namedCount = 0; var unnamedCount = 0; var newRoot = false; using (MemoryStream ms = new MemoryStream(BLTE.Parse(content))) using (BinaryReader bin = new BinaryReader(ms)) { var header = bin.ReadUInt32(); if (header == 1296454484) { uint totalFiles = bin.ReadUInt32(); uint namedFiles = bin.ReadUInt32(); newRoot = true; } else { bin.BaseStream.Position = 0; } while (bin.BaseStream.Position < bin.BaseStream.Length) { var count = bin.ReadUInt32(); var contentFlags = (ContentFlags)bin.ReadUInt32(); var localeFlags = (LocaleFlags)bin.ReadUInt32(); var entries = new RootEntry[count]; var filedataIds = new int[count]; var fileDataIndex = 0; for (var i = 0; i < count; ++i) { entries[i].localeFlags = localeFlags; entries[i].contentFlags = contentFlags; filedataIds[i] = fileDataIndex + bin.ReadInt32(); entries[i].fileDataID = (uint)filedataIds[i]; fileDataIndex = filedataIds[i] + 1; } if (!newRoot) { for (var i = 0; i < count; ++i) { entries[i].md5 = bin.Read <MD5Hash>(); entries[i].lookup = bin.ReadUInt64(); root.entriesLookup.Add(entries[i].lookup, entries[i]); root.entriesFDID.Add(entries[i].fileDataID, entries[i]); } } else { for (var i = 0; i < count; ++i) { entries[i].md5 = bin.Read <MD5Hash>(); } for (var i = 0; i < count; ++i) { if (contentFlags.HasFlag(ContentFlags.NoNames)) { entries[i].lookup = 0; unnamedCount++; } else { entries[i].lookup = bin.ReadUInt64(); namedCount++; root.entriesLookup.Add(entries[i].lookup, entries[i]); } root.entriesFDID.Add(entries[i].fileDataID, entries[i]); } } } } return(root); }
public static RootFile GetRoot(string url, string hash, bool parseIt = false) { var root = new RootFile { entriesLookup = new MultiDictionary <ulong, RootEntry>(), entriesFDID = new MultiDictionary <uint, RootEntry>(), }; byte[] content; if (url.StartsWith("http:")) { content = CDN.Get(url + "data/" + hash[0] + hash[1] + "/" + hash[2] + hash[3] + "/" + hash); } else { content = File.ReadAllBytes(Path.Combine(url, "data", "" + hash[0] + hash[1], "" + hash[2] + hash[3], hash)); } if (!parseIt) { return(root); } var hasher = new Jenkins96(); var namedCount = 0; var unnamedCount = 0; uint totalFiles = 0; uint namedFiles = 0; var newRoot = false; using (BinaryReader bin = new BinaryReader(new MemoryStream(BLTE.Parse(content)))) { var header = bin.ReadUInt32(); if (header == 1296454484) { totalFiles = bin.ReadUInt32(); namedFiles = bin.ReadUInt32(); newRoot = true; } else { bin.BaseStream.Position = 0; } while (bin.BaseStream.Position < bin.BaseStream.Length) { var count = bin.ReadUInt32(); var contentFlags = (ContentFlags)bin.ReadUInt32(); var localeFlags = (LocaleFlags)bin.ReadUInt32(); var entries = new RootEntry[count]; var filedataIds = new int[count]; var fileDataIndex = 0; for (var i = 0; i < count; ++i) { entries[i].localeFlags = localeFlags; entries[i].contentFlags = contentFlags; filedataIds[i] = fileDataIndex + bin.ReadInt32(); entries[i].fileDataID = (uint)filedataIds[i]; fileDataIndex = filedataIds[i] + 1; } if (!newRoot) { for (var i = 0; i < count; ++i) { entries[i].md5 = bin.Read <MD5Hash>(); entries[i].lookup = bin.ReadUInt64(); root.entriesLookup.Add(entries[i].lookup, entries[i]); root.entriesFDID.Add(entries[i].fileDataID, entries[i]); } } else { for (var i = 0; i < count; ++i) { entries[i].md5 = bin.Read <MD5Hash>(); } for (var i = 0; i < count; ++i) { if (contentFlags.HasFlag(ContentFlags.NoNames)) { //entries[i].lookup = hasher.ComputeHash("BY_FDID_" + entries[i].fileDataID); entries[i].lookup = 0; unnamedCount++; } else { entries[i].lookup = bin.ReadUInt64(); namedCount++; root.entriesLookup.Add(entries[i].lookup, entries[i]); } root.entriesFDID.Add(entries[i].fileDataID, entries[i]); } } } } return(root); }