Example #1
0
        /*public static byte[] CompressData(byte[] data, ZLibNet.CompressionLevel level = ZLibNet.CompressionLevel.Level9)
         * {
         *  using (var dest = new MemoryStream())
         *  {
         *      using (var source = new MemoryStream(data))
         *      {
         *          using (var deflateStream = new ZLibNet.DeflateStream(dest, ZLibNet.CompressionMode.Compress, level, true))
         *          {
         *              source.CopyTo(deflateStream);
         *
         *              // DOOM's compressed resources all end with 00 00 FF FF
         *              dest.SetLength(dest.Length + 4);
         *              dest.Position = dest.Length - 2;
         *              dest.WriteByte(0xFF);
         *              dest.WriteByte(0xFF);
         *
         *              /* DOOM's compressed resources all seem to have the first bit unset
         * tested by decompressing data and then recompressing using this Compress method, data is 1:1 except for the first bit (eg. our compressed data started with 0x7D, the games data would be 0x7C)
         * in one test, keeping the bit set made the games graphics screw up and trying to open multiplayer would crash
         * but unsetting this bit let the game work normally (using a slightly modified decl file also)
         * another test like this using data that was heavily modded still resulted in a glitched game, even with this bit unset
         * results inconclusive :(
         *              /*dest.Position = 0;
         *              byte b = (byte)ms.ReadByte();
         *              b &= byte.MaxValue ^ (1 << 0);
         *              ms.Position = 0;
         *              ms.WriteByte((byte)b);
         *
         *              return dest.ToArray();
         *          }
         *      }
         *  }
         * }*/

        private void addFilesFromFolder(string folder, string baseFolder, EndianIO destResources, ref List <string> addedFiles)
        {
            var dirs  = Directory.GetDirectories(folder);
            var files = Directory.GetFiles(folder);

            foreach (var file in files)
            {
                if (addedFiles.Contains(Path.GetFullPath(file)))
                {
                    continue;
                }

                if (folder == baseFolder && Path.GetFileName(file).ToLower() == "fileids.txt")
                {
                    continue; // don't want to add fileIds.txt from base
                }
                var filePath  = Path.GetFullPath(file).Substring(Path.GetFullPath(baseFolder).Length).Replace("\\", "/");
                var fileEntry = new DOOMResourceEntry(this);

                fileEntry.PatchFileNumber = PatchFileNumber;
                fileEntry.FileType        = "file";
                if (filePath.Contains(";")) // fileType is specified
                {
                    var idx = filePath.IndexOf(";");
                    fileEntry.FileType = filePath.Substring(idx + 1);
                    filePath           = filePath.Substring(0, idx);
                }
                fileEntry.FileName2 = filePath;
                fileEntry.FileName3 = filePath;

                bool needToPad = destResources.Stream.Length % 0x10 != 0;
                if (PatchFileNumber > 0 && destResources.Stream.Length == 4)
                {
                    needToPad = false; // for some reason patch files start at 0x4 instead of 0x10
                }
                if (needToPad)
                {
                    long numPadding = 0x10 - (destResources.Stream.Length % 0x10);
                    destResources.Stream.SetLength(destResources.Stream.Length + numPadding);
                }

                fileEntry.Offset = destResources.Stream.Length;

                byte[] fileData = File.ReadAllBytes(file);
                fileEntry.Size = fileEntry.CompressedSize = fileData.Length;

                fileEntry.ID = Entries.Count; // TODO: find out wtf the ID is needed for?
                destResources.Stream.Position = fileEntry.Offset;
                destResources.Writer.Write(fileData);

                Entries.Add(fileEntry);
                addedFiles.Add(Path.GetFullPath(file));
            }

            foreach (var dir in dirs)
            {
                addFilesFromFolder(dir, baseFolder, destResources, ref addedFiles);
            }
        }
Example #2
0
        public bool Load()
        {
            var indexExt = Path.GetExtension(IndexFilePath);

            if (!File.Exists(IndexFilePath) || (indexExt != ".index" && indexExt != ".pindex"))
            {
                return(false); // not an index file
            }
            if (!File.Exists(ResourceFilePath(0)))
            {
                return(false); // base resource data file not found!
            }
            resourceIOs = new Dictionary <string, EndianIO>();

            indexIO = new EndianIO(IndexFilePath, FileMode.Open);

            indexIO.Stream.Position = 0;
            var magic = indexIO.Reader.ReadInt32();

            if ((magic & 0xFFFFFF00) != 0x52455300)
            {
                Close();
                return(false); // not a RES file.
            }
            Header_Version   = (byte)(magic & 0xFF);
            Header_IndexSize = indexIO.Reader.ReadInt32();

            // init the base resource data file
            if (GetResourceIO(0) == null)
            {
                Close();
                return(false);
            }

            indexIO.Stream.Position = 0x20;
            indexIO.BigEndian       = true;
            Header_NumEntries       = indexIO.Reader.ReadInt32();

            Entries = new List <DOOMResourceEntry>();
            for (var i = 0; i < Header_NumEntries; i++)
            {
                var entry = new DOOMResourceEntry(this);
                entry.Read(indexIO);
                Entries.Add(entry);
                if (entry.PatchFileNumber > PatchFileNumber)
                {
                    PatchFileNumber = entry.PatchFileNumber; // highest PatchFileNumber must be our patch file index
                }
            }

            return(true);
        }
Example #3
0
        public long CopyEntryDataToStream(DOOMResourceEntry entry, Stream destStream, bool decompress = true)
        {
            var srcStream = entry.GetDataStream(decompress);

            if (srcStream == null)
            {
                return(0);
            }

            long copyLen = entry.CompressedSize;

            if (entry.IsCompressed && decompress)
            {
                copyLen = entry.Size;
            }

            return(Utility.StreamCopy(destStream, srcStream, 40960, copyLen));
        }