/// <summary> /// Adds a new <see cref="WADEntry"/> to this <see cref="WADFile"/> /// </summary> /// <param name="xxHash">The hash of the virtual path being added</param> /// <param name="data">Data of file being added</param> /// <param name="compressedEntry">Whether the data needs to be GZip compressed inside WAD</param> public WADEntry AddEntry(ulong xxHash, byte[] data, bool compressedEntry) { var newEntry = new WADEntry(this, xxHash, data, compressedEntry); AddEntry(newEntry); return(newEntry); }
/// <summary> /// Adds an existing <see cref="WADEntry"/> to this <see cref="WADFile"/> /// </summary> /// <param name="entry"></param> public void AddEntry(WADEntry entry) { if (!this._entries.Exists(x => x.XXHash == entry.XXHash) && entry._wad == this) { this._entries.Add(entry); this._entries.Sort(); } else { throw new Exception("An Entry with this path already exists"); } }
/// <summary> /// Writes this <see cref="WADFile"/> into the specified <see cref="Stream"/> /// </summary> /// <param name="stream">The <see cref="Stream"/> to write to</param> /// <param name="major">Which major version this <see cref="WADFile"/> should be saved as</param> /// <param name="minor">Which minor version this <see cref="WADFile"/> should be saved as</param> public void Write(Stream stream, byte major, byte minor) { if (major > 3) { throw new Exception("WAD File version: " + major + " either does not support writing or doesn't exist"); } using (BinaryWriter bw = new BinaryWriter(stream, Encoding.ASCII, true)) { bw.Write(Encoding.ASCII.GetBytes("RW")); bw.Write(major); bw.Write(minor); // Writing signatures if (major == 2) { bw.Write(new byte[84]); } else if (major == 3) { bw.Write(new byte[256]); } // Writing file checksums if (major == 2 || major == 3) { bw.Write((long)0); } int tocSize = (major == 1) ? 24 : 32; long tocOffset = stream.Position + 4; // Writing TOC info if (major < 3) { tocOffset += 4; bw.Write((ushort)tocOffset); bw.Write((ushort)tocSize); } bw.Write(this.Entries.Count); stream.Seek(tocOffset + (tocSize * this.Entries.Count), SeekOrigin.Begin); for (int i = 0; i < this.Entries.Count; i++) { WADEntry currentEntry = this.Entries[i]; currentEntry._isDuplicated = false; // Finding potential duplicated entry WADEntry duplicatedEntry = null; if (major != 1) { if (currentEntry.Type != EntryType.FileRedirection) { for (int j = 0; j < i; j++) { if (this.Entries[j].SHA.SequenceEqual(currentEntry.SHA)) { currentEntry._isDuplicated = true; duplicatedEntry = this.Entries[j]; break; } } } } // Writing data if (duplicatedEntry == null) { bw.Write(currentEntry.GetContent(false)); currentEntry._newData = null; currentEntry._dataOffset = (uint)stream.Position - currentEntry.CompressedSize; } else { currentEntry._dataOffset = duplicatedEntry._dataOffset; } } // Write TOC stream.Seek(tocOffset, SeekOrigin.Begin); foreach (WADEntry wadEntry in this.Entries) { wadEntry.Write(bw, major); } } this.Dispose(); this._stream = stream; this._major = major; this._minor = minor; }
/// <summary> /// Removes a <see cref="WADEntry"/> /// </summary> /// <param name="entry">The <see cref="WADEntry"/> to remove</param> public void RemoveEntry(WADEntry entry) { this._entries.Remove(entry); }