예제 #1
0
 /// <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");
     }
 }
예제 #2
0
        /// <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;
        }
예제 #3
0
 /// <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);
 }