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); }
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); }
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); }
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)); } }
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..."); } }
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)); } }
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); } ; } }