public static WAD Load(string path) { FileInfo fi = new FileInfo(path); Logger.LogToFile(Logger.LogLevel.Info, "{0}", path); WAD wad = new WAD(); wad.name = Path.GetFileNameWithoutExtension(path); wad.location = Path.GetDirectoryName(path) + "\\"; using (var br = new BinaryReader(fi.OpenRead())) { if (br.ReadByte() != 0x34 || br.ReadByte() != 0x12) { Logger.LogToFile(Logger.LogLevel.Error, "{0} isn't a valid WAD file", path); return null; } byte minor = br.ReadByte(); byte major = br.ReadByte(); wad.version = new Version(major, minor); wad.flags = (int)br.ReadUInt32(); int xmlLength = (int)br.ReadUInt32(); if (xmlLength > 0) { Logger.LogToFile(Logger.LogLevel.Error, "Unexpected data discovered. Aborting"); return null; } int namesLength = (int)br.ReadUInt32(); int endOfNamesBlock = (int)br.BaseStream.Position + namesLength; while (br.BaseStream.Position < endOfNamesBlock) { var entry = new WADEntry(); entry.Name = br.ReadString(); wad.contents.Add(entry); } } return wad; }
public void Extract(WADEntry file, string destination, bool createFullPath = true) { if (createFullPath) { destination = Path.Combine(destination, Path.GetDirectoryName(file.FullPath)); } if (!Directory.Exists(destination)) { Directory.CreateDirectory(destination); } using (BinaryWriter bw = new BinaryWriter(new FileStream(Path.Combine(destination, file.Name), FileMode.Create))) using (FileStream fs = new FileStream(Path.Combine(Location, $"{Name}.wad"), FileMode.Open)) using (BinaryReader br = new BinaryReader(fs)) { br.BaseStream.Seek(file.Offset, SeekOrigin.Begin); int length = br.ReadInt32(); if (length == -1) { bw.Write(br.ReadBytes(file.Size - 4)); } else { br.BaseStream.Seek(2, SeekOrigin.Current); using (MemoryStream ms = new MemoryStream(br.ReadBytes(file.Size - 2))) using (DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress)) { byte[] data = new byte[length]; ds.Read(data, 0, length); bw.Write(data, 0, data.Length); } } } }
public void Extract(WADEntry file, string destination) { if (!Directory.Exists(destination)) { Directory.CreateDirectory(destination); } using (var bw = new BinaryWriter(new FileStream(destination + "\\" + file.Name, FileMode.Create))) { using (var fs = new FileStream(this.location + this.name + ".wad", FileMode.Open)) { fs.Seek(file.Offset, SeekOrigin.Begin); var buff = new byte[file.Size]; fs.Read(buff, 0, file.Size); bw.Write(buff); buff = null; } } }
public static WAD Load(string path) { FileInfo fi = new FileInfo(path); Logger.LogToFile(Logger.LogLevel.Info, "{0}", path); WAD wad = new WAD { Name = Path.GetFileNameWithoutExtension(path), Location = Path.GetDirectoryName(path) }; using (BinaryReader br = new BinaryReader(fi.OpenRead())) { if (br.ReadByte() != 0x34 || br.ReadByte() != 0x12) { Logger.LogToFile(Logger.LogLevel.Error, "{0} isn't a valid WAD file", path); return(null); } byte minor = br.ReadByte(); byte major = br.ReadByte(); wad.Version = new Version(major, minor); wad.Flags = (WADFlags)br.ReadUInt32(); int xmlLength = (int)br.ReadUInt32(); if (xmlLength > 0) { Logger.LogToFile(Logger.LogLevel.Error, "Unexpected data discovered. Aborting"); return(null); } int namesLength = (int)br.ReadUInt32(); int nameBlockStart = (int)br.BaseStream.Position; int nameBlockEnd = (int)br.BaseStream.Position + namesLength; Dictionary <int, string> names = new Dictionary <int, string>(); while (br.BaseStream.Position < nameBlockEnd && br.PeekChar() != 0) { names.Add((int)(br.BaseStream.Position - nameBlockStart), br.ReadNullTerminatedString()); } br.BaseStream.Seek(nameBlockEnd, SeekOrigin.Begin); if (wad.Flags.HasFlag(WADFlags.HasDataTimes)) { int count = br.ReadInt32(); for (int i = 0; i < count; i++) { br.ReadInt32(); // index (with bit 0x1 set) br.ReadInt32(); // dos date time? time added to archive? } } int fileCount = br.ReadInt32(); int folderCount = br.ReadInt32(); int offsetCount = br.ReadInt32(); List <int> offsets = new List <int>(); for (int i = 0; i < offsetCount; i++) { offsets.Add(br.ReadInt32()); } void processFileEntry(WADEntry parent) { WADEntry entry = new WADEntry { Name = names[br.ReadInt32()], Size = br.ReadInt32(), ParentEntry = parent, Offset = offsets[(int)(br.ReadUInt32() & 0x00FFFFFF)] }; br.ReadInt32(); // Unknown wad.Contents.Add(entry); } void processDirectoryEntry(WADEntry parent = null) { WADEntry entry = new WADEntry { Name = names[br.ReadInt32()], IsDirectory = true, ParentEntry = parent }; wad.Contents.Add(entry); int fileEntries = br.ReadInt32(); int folderEntries = br.ReadInt32(); br.ReadInt32(); // unknown for (int i = 0; i < folderEntries; i++) { processDirectoryEntry(entry); } for (int i = 0; i < fileEntries; i++) { processFileEntry(entry); } } processDirectoryEntry(); } return(wad); }