finish() public method

public finish ( ) : void
return void
Beispiel #1
0
 public static void DecompressData(byte[] inData, out byte[] outData)
 {
     using (MemoryStream outMemoryStream = new MemoryStream())
     using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream))
     using (Stream inMemoryStream = new MemoryStream(inData))
     {
         CopyStream(inMemoryStream, outZStream);
         outZStream.finish();
         outData = outMemoryStream.ToArray();
     }
 }
Beispiel #2
0
 public static void CompressData(byte[] inData, out byte[] outData)
 {
     using (MemoryStream outMemoryStream = new MemoryStream())
     using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_DEFAULT_COMPRESSION))
     using (Stream inMemoryStream = new MemoryStream(inData))
     {
         CopyStream(inMemoryStream, outZStream);
         outZStream.finish();
         outData = outMemoryStream.ToArray();
     }
 }
Beispiel #3
0
 public static byte[] Compress(byte[] inputBytes)
 {
     using (MemoryStream stream = new MemoryStream())
     {
         using (ZOutputStream stream2 = new ZOutputStream(stream, 0))
         {
             stream2.Write(inputBytes, 0, inputBytes.Length);
             stream2.finish();
             return stream.ToArray();
         }
     }
 }
Beispiel #4
0
        private bool ReplaceContentHelperFunc(byte[] content, FileStream datFileStream)
        {
            // Store the old offsets just in case we need to perform a restore.
            // This actually isn't necessary currently, since the raf directory file is saved after packing.
            UInt32 oldOffset = FileOffset;
            UInt32 oldSize   = FileSize;

            try
            {
                // Navigate to the end of it
                datFileStream.Seek(0, SeekOrigin.End);
                UInt32 offset = (UInt32)datFileStream.Length;

                FileInfo fInfo = new FileInfo(m_fileName);

                // .fsb, .fev, and .gfx files aren't compressed
                byte[] finalContent;
                if (fInfo.Extension == ".fsb" || fInfo.Extension == ".fev" || fInfo.Extension == ".gfx")
                {
                    finalContent = content;
                }
                else
                {
                    // Start of compression
                    MemoryStream       mStream = new MemoryStream();
                    zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                    oStream.Write(content, 0, content.Length);
                    oStream.finish();
                    finalContent = mStream.ToArray();
                }

                // Write the data to the end of the .dat file
                datFileStream.Write(finalContent, 0, finalContent.Length);

                // Update entry values to represent the new changes
                FileOffset = offset;
                FileSize   = (UInt32)finalContent.Length;

                return(true);
            }
            catch (Exception)
            {
                FileOffset = oldOffset;
                FileSize   = oldSize;

                return(false);
            }
        }
        private bool ReplaceContentHelperFunc(byte[] content, FileStream datFileStream)
        {
            // Store the old offsets just in case we need to perform a restore.
            // This actually isn't necessary currently, since the raf directory file is saved after packing.
            var oldOffset = FileOffset;
            var oldSize = FileSize;

            try
            {
                // Navigate to the end of it
                datFileStream.Seek(0, SeekOrigin.End);
                var offset = (UInt32) datFileStream.Length;

                var fInfo = new FileInfo(FileName);

                // .fsb, .fev, and .gfx files aren't compressed
                byte[] finalContent;
                if (fInfo.Extension == ".fsb" || fInfo.Extension == ".fev" || fInfo.Extension == ".gfx")
                {
                    finalContent = content;
                }
                else
                {
                    // Start of compression
                    var mStream = new MemoryStream();
                    var oStream = new ZOutputStream(mStream, zlibConst.Z_DEFAULT_COMPRESSION);
                    //using default compression level
                    oStream.Write(content, 0, content.Length);
                    oStream.finish();
                    finalContent = mStream.ToArray();
                }

                // Write the data to the end of the .dat file
                datFileStream.Write(finalContent, 0, finalContent.Length);

                // Update entry values to represent the new changes
                FileOffset = offset;
                FileSize = (UInt32) finalContent.Length;

                return true;
            }
            catch (Exception)
            {
                FileOffset = oldOffset;
                FileSize = oldSize;

                return false;
            }
        }
        public static OSD ZDecompressOSD(byte[] data)
        {
            OSD ret;

            using (MemoryStream input = new MemoryStream(data))
            using (MemoryStream output = new MemoryStream())
            using (ZOutputStream zout = new ZOutputStream(output))
            {
                CopyStream(input, zout);
                zout.finish();
                output.Seek(0, SeekOrigin.Begin);
                ret = OSDParser.DeserializeLLSDBinary(output);
            }

            return ret;
        }
        public static byte[] ZCompressOSD(OSD data)
        {
            byte[] ret = null;

            using (MemoryStream outMemoryStream = new MemoryStream())
            using (ZOutputStream outZStream = new ZOutputStream(outMemoryStream, zlibConst.Z_BEST_COMPRESSION))
            using (Stream inMemoryStream = new MemoryStream(OSDParser.SerializeLLSDBinary(data, false)))
            {
                CopyStream(inMemoryStream, outZStream);
                outZStream.finish();
                ret = outMemoryStream.ToArray();
            }

            return ret;
        }
Beispiel #8
0
        //Inserts a file into the raf archive...
        public bool InsertFile(string fileName, byte[] content, TextWriter ostream)
        {
            if (ostream == null)
                ostream = new StreamWriter(Stream.Null);

            ostream.WriteLine("    Insert: " + fileName);
            ostream.WriteLine("        To: " + GetID());

            RAFFileListEntry fileentry = this.GetDirectoryFile().GetFileList().GetFileEntry(fileName);
            if (fileentry == null)
            {
                //Define a new entry
                ostream.WriteLine("# Create new entry in RAF Archive, using experimental hash calculations");
                ostream.WriteLine("    Get DAT File Stream");
                FileStream datFileStream = GetDataFileContentStream();
                //navigate to the end of it, add the file.
                datFileStream.Seek(0, SeekOrigin.End);
                UInt32 offset = (UInt32)datFileStream.Length;

                byte[] finalContent;
                if (nocompress.Contains(fileName))
                {
                    finalContent = content;
                }
                else
                {
                    ostream.WriteLine("    Begin compression of content");
                    MemoryStream mStream = new MemoryStream();
                    zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                    oStream.Write(content, 0, content.Length);
                    oStream.finish();
                    finalContent = mStream.ToArray();
                }

                ostream.WriteLine("    Begin DAT Write");
                datFileStream.Write(finalContent, 0, finalContent.Length);

                ostream.WriteLine("    Add file entry to in memory directory...");
                UInt32 strTableIndex = directoryFile.GetStringTable().Add(fileName);
                directoryFile.CreateFileEntry(fileName, offset, (UInt32)finalContent.Length, strTableIndex);
                //directoryFile.Save();
                //datFileStream.Close();
                ostream.WriteLine("    Done.");
                return true;

            }
            else
            {
                //store the old offsets just in case we need to perform a restore.
                //This actually isn't necessary currently, since the raf directory file is saved
                //After packing.
                UInt32 oldOffset = (UInt32)fileentry.FileOffset;
                UInt32 oldSize = (UInt32)fileentry.FileSize;
                ostream.WriteLine("Old Offset: " + oldOffset + "; Old Size: " + oldSize);

                ostream.WriteLine("Begin modify game files...  This may take a while");
                try
                {
                    ostream.WriteLine("    Get File Stream");
                    FileStream datFileStream = GetDataFileContentStream();
                    //navigate to the end of it, add the file.
                    datFileStream.Seek(0, SeekOrigin.End);
                    UInt32 offset = (UInt32)datFileStream.Length;

                    byte[] finalContent;
                    if (nocompress.Contains(fileName))
                    {
                        finalContent = content;
                    }
                    else
                    {
                        ostream.WriteLine("    Begin compression of content");
                        MemoryStream mStream = new MemoryStream();
                        zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                        oStream.Write(content, 0, content.Length);
                        oStream.finish();
                        finalContent = mStream.ToArray();
                    }

                    ostream.WriteLine("    Begin DAT Write");
                    datFileStream.Write(finalContent, 0, finalContent.Length);

                    ostream.WriteLine("    Begin FileEntry Write");
                    fileentry.FileOffset = offset;
                    fileentry.FileSize = (UInt32)finalContent.Length;
                    //directoryFile.Save();

                    //datFileStream.Close();
                    ostream.WriteLine("    Done.");
                    return true;
                }
                catch (Exception e)
                {
                    ostream.WriteLine("!! An error occurred in inserting a file.");
                    ostream.WriteLine("!! Note that the content of the raf archive has been added to");
                    ostream.WriteLine("!! But the directory file that points the game to the data in the content file");
                    ostream.WriteLine("!! Has not been modified.  In other words, if the game read the RAF archive now");
                    ostream.WriteLine("!! It wouldn't see a difference.");
                    ostream.WriteLine("!! However, the RAF archive is a bit bigger than before.");
                    ostream.WriteLine(e.ToString());

                    fileentry.FileOffset = oldOffset;
                    fileentry.FileSize = oldSize;
                    //directoryFile.GetContent();
                    return false;
                }
            }
        }
Beispiel #9
0
        public bool PackRAF(string sourceDirectory, string targetDirectory)
        {
            //RAFHashManager.Init(); //Inits if it needs to load the hashes dict...

            //archivedPaths = RAFHashManager.GetKeys();

            uncompressedFiles = new List<string>();
            uncompressedFiles.AddRange(File.ReadAllLines(Environment.CurrentDirectory + "\\nocompress.txt"));

            sourceDirectory = sourceDirectory.Replace("/", "\\");
            String[] files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories);

            ostream.WriteLine("Begin packing RAF");

            ostream.WriteLine("Count content bytes + file name bytes");

            UInt32 totalNameBytes = 0;
            List<UInt32> stringTableContentOffsets = new List<UInt32>();
            List<String> archivedPaths = new List<string>();        //Misnomer - name of the files once archived
            foreach (String filePath in files)
            {
                string archivePath = filePath.Replace(sourceDirectory, "").Replace("\\", "/");
                stringTableContentOffsets.Add((UInt32)totalNameBytes);
                totalNameBytes += (UInt32)(archivePath.Length + 1);
                archivedPaths.Add(archivePath);//raf uses / in storage name.
            }
            foreach (String archivePath in archivedPaths)
            {
                stringTableContentOffsets.Add((UInt32)totalNameBytes);
                totalNameBytes += (UInt32)(archivePath.Length + 1);
                //archivedPaths.Add(archivePath);//raf uses / in storage name.
            }

            //Calculate total bytes of header file: 
            // ulong magic = 0x18BE0EF0                             6*4
            // ulong version = 1
            // toc:
            // ulong mgrIndex = 0?
            // ulong fileListOffset 
            // ulong tableListOffset
            // ...filler...
            // @fileListOffset:
            //      header:
            //          ulong countFiles                            4
            //      ulong hashName                                  4*4*n
            //      ulong offsetInDataFile
            //      ulong size(Compressed/noncompressed)
            //      ulong name string @ string table
            // ....filler....
            // @tableListOffset
            //      header:                                         4*2
            //          ulong sizeOfData ( including header )
            //          ulong stringsContained
            //      ulong offsetOfDataAfterTableListOffset          4*2*n
            //      ulong stringLength (including null terminating char)

            //TODO: Check if string table contains strings other than filenames

            //List<byte> datBytes = new List<byte>();
            UInt32 totalDatBytes = 0;
            List<UInt32> datFileOffsets = new List<UInt32>();
            List<UInt32> fileSizes = new List<UInt32>();
            //We start by packing the files into the .dat... We just archive all files and remember their offsets for later

            PrepareDirectory(targetDirectory);
            FileStream datFileStream = File.Create(targetDirectory + "\\output.raf.dat");
            for(int i = 0; i < archivedPaths.Count; i++)
            {
                //datFileOffsets.Add((UInt32)datBytes.Count);

                //LoL_Audio.fev and LoL_Audio.fsb aren't compressed.  We write them raw.
                if (uncompressedFiles.Contains(archivedPaths[i].ToLower()))
                {
                    //Write raw
                    ostream.WriteLine("No Compress: " + archivedPaths[i]);
                    fileSizes.Add((UInt32)new FileInfo(sourceDirectory + archivedPaths[i]).Length);
                    datFileOffsets.Add((UInt32)totalDatBytes);
                    //datBytes.AddRange(File.ReadAllBytes(sourceDirectory + archivedPaths[i]));
                    byte[] content = File.ReadAllBytes(sourceDirectory + archivedPaths[i]);
                    datFileStream.Write(content, 0, content.Length);
                    totalDatBytes += (UInt32)content.Length;
                }
                else
                {
                    ostream.WriteLine("Compress: " + archivedPaths[i]);
                    //FileStream fStream = new FileStream(sourceDirectory + archivedPaths[i], FileMode.Open);
                    //fStream.Seek(0, SeekOrigin.Begin);
                    //ostreamWriteLine("FStream Length: " + fStream.Length);
                    byte[] fileContent = File.ReadAllBytes(sourceDirectory + archivedPaths[i]);
                    ostream.WriteLine("Original Size:" + fileContent.Length);
                    MemoryStream mStream = new MemoryStream();
                    zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                    oStream.Write(fileContent, 0, fileContent.Length);
                    oStream.finish();
                    byte[] compressedContent = mStream.ToArray();
                    datFileOffsets.Add((UInt32)totalDatBytes);
                    datFileStream.Write(compressedContent, 0, compressedContent.Length);
                    //datBytes.AddRange(compressedContent);//contentBuffer.SubArray(0, length));
                    //count += (UInt32)length;
                    totalDatBytes += (UInt32)compressedContent.Length;
                    ostream.WriteLine("Done, {0} bytes".F(compressedContent.Length));
                    fileSizes.Add((UInt32)compressedContent.Length);
                }
            }

            UInt32 finalLength = (UInt32)(2*4 + 3*4 + 4 + 4*4*archivedPaths.Count + 4*2 + 4*2*archivedPaths.Count + totalNameBytes);
            byte[] buffer = new byte[finalLength]; //0x18BE0EF0.. note that the settings to 0 aren't necessary, but they're
                                                    // for readability
            //Magic
            StoreUInt32InBuffer((UInt32)0x18BE0EF0, (UInt32)0, ref buffer);

            //Version
            StoreUInt32InBuffer((UInt32)0x00000001, (UInt32)4, ref buffer);

            //mgrIndex = 0
            StoreUInt32InBuffer((UInt32)0x00000000, (UInt32)8, ref buffer);
            
            //fileListOffset
            StoreUInt32InBuffer((UInt32)        20, (UInt32)12, ref buffer);
            
            //stringTableOffset
            StoreUInt32InBuffer((UInt32)(20+4+16*archivedPaths.Count), (UInt32)16, ref buffer);

            //Start file list
            UInt32 offset = 0x14; //20, header of file list

            //Store # entries in list
            StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
            offset += 4;

            //Store entries
            for (int i = 0; i < archivedPaths.Count; i++)
            {
                ostream.WriteLine("Store Entry: " + archivedPaths[i]);
                //Hash of string name?  Get it from previous RAF files.
                StoreUInt32InBuffer(GetStringHash(archivedPaths[i]) , offset, ref buffer);

                // Offset to the start of the archived file in the data file
                ostream.WriteLine("  Dat Offset: " + datFileOffsets[i].ToString("x") + "; i="+i);
                StoreUInt32InBuffer(datFileOffsets[i]               , offset+4, ref buffer);

                // Size of this archived file
                StoreUInt32InBuffer(fileSizes[i]                    , offset+8, ref buffer);
                // Index of the name of the archvied file in the string table
                StoreUInt32InBuffer((UInt32)i                       , offset+12, ref buffer);
                offset += 16;
            }

            //Create String Tables
            UInt32 stringTableOffset = offset = (UInt32)(20 + 4 + 16 * archivedPaths.Count); //This should be equivalent to offset= offset at the moment...

            //Header: Uint32 size of all data including header
            //        UINT32 Number of strings in the table

            StoreUInt32InBuffer((UInt32)totalNameBytes, offset, ref buffer);
            offset += 4;
            StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
            offset += 4;
            //Write entries: UINT32 Offset from start of table, UINT32 Size of String + NUL
            //Also write the actual string values
            for (int i = 0; i < archivedPaths.Count; i++)
            {
                ostream.WriteLine("Store String: " + archivedPaths[i]);
                //Write the offset for the string after the table's offset
                //               offset after table = header + entry count * 8 + [strings offset] * 8
                UInt32 offsetAfterTable = (UInt32)(8 + archivedPaths.Count * 8 + stringTableContentOffsets[i]);
                StoreUInt32InBuffer(offsetAfterTable, offset, ref buffer);
                offset += 4;
                
                //Length
                byte[] stringBytes = Encoding.ASCII.GetBytes(archivedPaths[i]);
                StoreUInt32InBuffer((UInt32)archivedPaths[i].Length + 1, offset, ref buffer);
                offset += 4;

                ostream.WriteLine("  STO:" + stringTableOffset.ToString("x"));
                ostream.WriteLine("  finalIndex:" + (stringTableOffset + 8 + archivedPaths.Count * 8 + stringTableContentOffsets[i]).ToString("x"));
                //Copy the string contents to where offsetAfterTable points to
                for (int j = 0; j < stringBytes.Length; j++)
                {
                    buffer[stringTableOffset+ 8 + archivedPaths.Count * 8 + stringTableContentOffsets[i] + j] = stringBytes[j];
                }
                //StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
                //offset += 4;                
            }

            //We are done.  Write the files
            ostream.WriteLine("All files processed.  Writing to disk.");

            //buffer
            ostream.WriteLine("Prepare.");
            PrepareDirectory(targetDirectory);
            
            ostream.WriteLine("Write RAF Directory File.");
            File.WriteAllBytes(targetDirectory + "\\output.raf", buffer);

            ostream.WriteLine("Finalize");
            datFileStream.Flush();
            datFileStream.Close();
            //ostreamWriteLine("Write RAF Content File. Length:"+datBytes.Count);
            //File.WriteAllBytes(targetDirectory + "\\output.raf.dat", datBytes.ToArray());
            return true;
        }
Beispiel #10
0
 /// <summary>
 /// 解压流
 /// </summary>
 /// <param name="SourceStream">需要被解缩的流数据</param>
 /// <returns></returns>
 public static Stream DecompressStream(Stream SourceStream)
 {
     try
     {
         MemoryStream stmOutput = new MemoryStream();
         ZOutputStream outZStream = new ZOutputStream(stmOutput);
         CopyStream(SourceStream, outZStream);
         outZStream.finish();
         return stmOutput;
     }
     catch
     {
         return null;
     }
 }
Beispiel #11
0
 /// <summary>
 /// 压缩流
 /// </summary>
 /// <param name="SourceStream">需要被压缩的流数据</param>
 /// <returns></returns>
 public static Stream CompressStream(Stream SourceStream)
 {
     try
     {
         MemoryStream stmOutTemp = new MemoryStream();
         ZOutputStream outZStream = new ZOutputStream(stmOutTemp, zlibConst.Z_DEFAULT_COMPRESSION);
         CopyStream(SourceStream, outZStream);
         outZStream.finish();
         return stmOutTemp;
     }
     catch
     {
         return null;
     }
 }
Beispiel #12
0
        public bool PackRAF(string sourceDirectory, string targetDirectory)
        {
            //RAFHashManager.Init(); //Inits if it needs to load the hashes dict...

            //archivedPaths = RAFHashManager.GetKeys();

            uncompressedFiles = new List <string>();
            uncompressedFiles.AddRange(File.ReadAllLines(Environment.CurrentDirectory + "\\nocompress.txt"));

            sourceDirectory = sourceDirectory.Replace("/", "\\");
            String[] files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories);

            ostream.WriteLine("Begin packing RAF");

            ostream.WriteLine("Count content bytes + file name bytes");

            UInt32        totalNameBytes            = 0;
            List <UInt32> stringTableContentOffsets = new List <UInt32>();
            List <String> archivedPaths             = new List <string>(); //Misnomer - name of the files once archived

            foreach (String filePath in files)
            {
                string archivePath = filePath.Replace(sourceDirectory, "").Replace("\\", "/");
                stringTableContentOffsets.Add((UInt32)totalNameBytes);
                totalNameBytes += (UInt32)(archivePath.Length + 1);
                archivedPaths.Add(archivePath);//raf uses / in storage name.
            }
            foreach (String archivePath in archivedPaths)
            {
                stringTableContentOffsets.Add((UInt32)totalNameBytes);
                totalNameBytes += (UInt32)(archivePath.Length + 1);
                //archivedPaths.Add(archivePath);//raf uses / in storage name.
            }

            //Calculate total bytes of header file:
            // ulong magic = 0x18BE0EF0                             6*4
            // ulong version = 1
            // toc:
            // ulong mgrIndex = 0?
            // ulong fileListOffset
            // ulong tableListOffset
            // ...filler...
            // @fileListOffset:
            //      header:
            //          ulong countFiles                            4
            //      ulong hashName                                  4*4*n
            //      ulong offsetInDataFile
            //      ulong size(Compressed/noncompressed)
            //      ulong name string @ string table
            // ....filler....
            // @tableListOffset
            //      header:                                         4*2
            //          ulong sizeOfData ( including header )
            //          ulong stringsContained
            //      ulong offsetOfDataAfterTableListOffset          4*2*n
            //      ulong stringLength (including null terminating char)

            //TODO: Check if string table contains strings other than filenames

            //List<byte> datBytes = new List<byte>();
            UInt32        totalDatBytes  = 0;
            List <UInt32> datFileOffsets = new List <UInt32>();
            List <UInt32> fileSizes      = new List <UInt32>();

            //We start by packing the files into the .dat... We just archive all files and remember their offsets for later

            PrepareDirectory(targetDirectory);
            FileStream datFileStream = File.Create(targetDirectory + "\\output.raf.dat");

            for (int i = 0; i < archivedPaths.Count; i++)
            {
                //datFileOffsets.Add((UInt32)datBytes.Count);

                //LoL_Audio.fev and LoL_Audio.fsb aren't compressed.  We write them raw.
                if (uncompressedFiles.Contains(archivedPaths[i].ToLower()))
                {
                    //Write raw
                    ostream.WriteLine("No Compress: " + archivedPaths[i]);
                    fileSizes.Add((UInt32) new FileInfo(sourceDirectory + archivedPaths[i]).Length);
                    datFileOffsets.Add((UInt32)totalDatBytes);
                    //datBytes.AddRange(File.ReadAllBytes(sourceDirectory + archivedPaths[i]));
                    byte[] content = File.ReadAllBytes(sourceDirectory + archivedPaths[i]);
                    datFileStream.Write(content, 0, content.Length);
                    totalDatBytes += (UInt32)content.Length;
                }
                else
                {
                    ostream.WriteLine("Compress: " + archivedPaths[i]);
                    //FileStream fStream = new FileStream(sourceDirectory + archivedPaths[i], FileMode.Open);
                    //fStream.Seek(0, SeekOrigin.Begin);
                    //ostreamWriteLine("FStream Length: " + fStream.Length);
                    byte[] fileContent = File.ReadAllBytes(sourceDirectory + archivedPaths[i]);
                    ostream.WriteLine("Original Size:" + fileContent.Length);
                    MemoryStream       mStream = new MemoryStream();
                    zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                    oStream.Write(fileContent, 0, fileContent.Length);
                    oStream.finish();
                    byte[] compressedContent = mStream.ToArray();
                    datFileOffsets.Add((UInt32)totalDatBytes);
                    datFileStream.Write(compressedContent, 0, compressedContent.Length);
                    //datBytes.AddRange(compressedContent);//contentBuffer.SubArray(0, length));
                    //count += (UInt32)length;
                    totalDatBytes += (UInt32)compressedContent.Length;
                    ostream.WriteLine("Done, {0} bytes".F(compressedContent.Length));
                    fileSizes.Add((UInt32)compressedContent.Length);
                }
            }

            UInt32 finalLength = (UInt32)(2 * 4 + 3 * 4 + 4 + 4 * 4 * archivedPaths.Count + 4 * 2 + 4 * 2 * archivedPaths.Count + totalNameBytes);

            byte[] buffer = new byte[finalLength]; //0x18BE0EF0.. note that the settings to 0 aren't necessary, but they're
                                                   // for readability
            //Magic
            StoreUInt32InBuffer((UInt32)0x18BE0EF0, (UInt32)0, ref buffer);

            //Version
            StoreUInt32InBuffer((UInt32)0x00000001, (UInt32)4, ref buffer);

            //mgrIndex = 0
            StoreUInt32InBuffer((UInt32)0x00000000, (UInt32)8, ref buffer);

            //fileListOffset
            StoreUInt32InBuffer((UInt32)20, (UInt32)12, ref buffer);

            //stringTableOffset
            StoreUInt32InBuffer((UInt32)(20 + 4 + 16 * archivedPaths.Count), (UInt32)16, ref buffer);

            //Start file list
            UInt32 offset = 0x14; //20, header of file list

            //Store # entries in list
            StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
            offset += 4;

            //Store entries
            for (int i = 0; i < archivedPaths.Count; i++)
            {
                ostream.WriteLine("Store Entry: " + archivedPaths[i]);
                //Hash of string name?  Get it from previous RAF files.
                StoreUInt32InBuffer(GetStringHash(archivedPaths[i]), offset, ref buffer);

                // Offset to the start of the archived file in the data file
                ostream.WriteLine("  Dat Offset: " + datFileOffsets[i].ToString("x") + "; i=" + i);
                StoreUInt32InBuffer(datFileOffsets[i], offset + 4, ref buffer);

                // Size of this archived file
                StoreUInt32InBuffer(fileSizes[i], offset + 8, ref buffer);
                // Index of the name of the archvied file in the string table
                StoreUInt32InBuffer((UInt32)i, offset + 12, ref buffer);
                offset += 16;
            }

            //Create String Tables
            UInt32 stringTableOffset = offset = (UInt32)(20 + 4 + 16 * archivedPaths.Count); //This should be equivalent to offset= offset at the moment...

            //Header: Uint32 size of all data including header
            //        UINT32 Number of strings in the table

            StoreUInt32InBuffer((UInt32)totalNameBytes, offset, ref buffer);
            offset += 4;
            StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
            offset += 4;
            //Write entries: UINT32 Offset from start of table, UINT32 Size of String + NUL
            //Also write the actual string values
            for (int i = 0; i < archivedPaths.Count; i++)
            {
                ostream.WriteLine("Store String: " + archivedPaths[i]);
                //Write the offset for the string after the table's offset
                //               offset after table = header + entry count * 8 + [strings offset] * 8
                UInt32 offsetAfterTable = (UInt32)(8 + archivedPaths.Count * 8 + stringTableContentOffsets[i]);
                StoreUInt32InBuffer(offsetAfterTable, offset, ref buffer);
                offset += 4;

                //Length
                byte[] stringBytes = Encoding.ASCII.GetBytes(archivedPaths[i]);
                StoreUInt32InBuffer((UInt32)archivedPaths[i].Length + 1, offset, ref buffer);
                offset += 4;

                ostream.WriteLine("  STO:" + stringTableOffset.ToString("x"));
                ostream.WriteLine("  finalIndex:" + (stringTableOffset + 8 + archivedPaths.Count * 8 + stringTableContentOffsets[i]).ToString("x"));
                //Copy the string contents to where offsetAfterTable points to
                for (int j = 0; j < stringBytes.Length; j++)
                {
                    buffer[stringTableOffset + 8 + archivedPaths.Count * 8 + stringTableContentOffsets[i] + j] = stringBytes[j];
                }
                //StoreUInt32InBuffer((UInt32)archivedPaths.Count, offset, ref buffer);
                //offset += 4;
            }

            //We are done.  Write the files
            ostream.WriteLine("All files processed.  Writing to disk.");

            //buffer
            ostream.WriteLine("Prepare.");
            PrepareDirectory(targetDirectory);

            ostream.WriteLine("Write RAF Directory File.");
            File.WriteAllBytes(targetDirectory + "\\output.raf", buffer);

            ostream.WriteLine("Finalize");
            datFileStream.Flush();
            datFileStream.Close();
            //ostreamWriteLine("Write RAF Content File. Length:"+datBytes.Count);
            //File.WriteAllBytes(targetDirectory + "\\output.raf.dat", datBytes.ToArray());
            return(true);
        }
Beispiel #13
0
        // serialize all components into a stream, then compress and write the result to disk. Operation derived from
        // the original SiD C source
        public void Save(String filename)
        {
            MemoryStream ms = new MemoryStream(mComponents.Count * 1064);
              using (ms)
              {
            using (BinaryWriter b = new BinaryWriter(ms))
            {
              b.Write(ByteUtils.SwapUInt32((UInt32)mComponents.Count));

              foreach (SiDComponent exC in mComponents)
              {
            byte[] compName = ASCIIEncoding.UTF8.GetBytes(exC.Name);
            byte[] typeName = ASCIIEncoding.UTF8.GetBytes(exC.ResourceTypeName);
            UID uid = exC.getUID();

            b.Write(typeName);
            b.Write('\0');

            b.Write(uid.UIDBytes);

            b.Write(compName);
            b.Write('\0');

            byte[] dataBuf = exC.SaveToByteStream();
            b.Write(ByteUtils.SwapUInt32((UInt32)dataBuf.Length));
            b.Write(dataBuf);
              }

              Int32 uncompressedSize = (Int32)ms.Length;

              MemoryStream packMem = new MemoryStream(uncompressedSize);
              using (ZOutputStream zStream = new ZOutputStream(packMem, 9))
              {
            zStream.Write(ms.ToArray(), 0, (Int32)ms.Length);
            zStream.finish();

            using (FileStream fs = File.Open(filename, FileMode.Create))
            {
              using (BinaryWriter fb = new BinaryWriter(fs))
              {
                fb.Write(ByteUtils.SwapUInt32((UInt32)uncompressedSize));
                fb.Write(packMem.ToArray(), 0, (Int32)packMem.Length);
              }

              fs.Close();
            }
              }
            }
              }
        }
        /// <summary>
        /// Old Decompress method not using .NET compressor
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] DecompressOld(byte[] Data)
        {
            byte[] decompressedPixelData = new byte[UncompressedLength];

            // ZLIB
            if (version > BgfFile.VERSION9)
            {
                // init streams
                MemoryStream destStream = new MemoryStream(decompressedPixelData, true);
                ZOutputStream destZ = new ZOutputStream(destStream);

                // decompress
                destZ.Write(Data, 0, Data.Length);
                destZ.Flush();
                destZ.finish();

                // cleanup
                destStream.Dispose();
                destZ.Dispose();
            }
            // CRUSH
            else
            {
            #if WINCLR && X86
                // decompress
                Crush32.Decompress(Data, 0, decompressedPixelData, 0, (int)UncompressedLength, CompressedLength);
            #else
                throw new Exception(ERRORCRUSHPLATFORM);
            #endif
            }

            // set decompressed array to pixeldata
            return decompressedPixelData;
        }
        /// <summary>
        /// Returns a compressed byte[] of PixelData argument
        /// </summary>
        /// <param name="Data"></param>
        /// <returns></returns>
        public byte[] Compress(byte[] Data)
        {
            // allocate a buffer with uncompressed length to write compressed stream to
            byte[] tempBuffer = new byte[UncompressedLength];
            int compressedLength;

            // ZLIB
            if (version > BgfFile.VERSION9)
            {
                // init streams
                MemoryStream destStream = new MemoryStream(tempBuffer, true);
                ZOutputStream destZ = new ZOutputStream(destStream, zlibConst.Z_BEST_COMPRESSION);

                // compress
                destZ.Write(Data, 0, Data.Length);
                destZ.Flush();
                destZ.finish();

                // update compressed length
                compressedLength = (int)destZ.TotalOut;

                // cleanup
                destStream.Dispose();
                destZ.Dispose();
            }
            // CRUSH
            else
            {
            #if WINCLR && X86
                // compress to tempBuffer
                compressedLength = Crush32.Compress(Data, 0, tempBuffer, 0, (int)UncompressedLength);
            #else
                throw new Exception(ERRORCRUSHPLATFORM);
            #endif
            }

            // copy all bytes we actually used from tempBuffer to new PixelData
            byte[] newPixelData = new byte[compressedLength];
            Array.Copy(tempBuffer, 0, newPixelData, 0, compressedLength);

            return newPixelData;
        }
Beispiel #16
0
        //Inserts a file into the raf archive...
        public bool InsertFile(string fileName, byte[] content, TextWriter ostream)
        {
            if (ostream == null)
            {
                ostream = new StreamWriter(Stream.Null);
            }

            ostream.WriteLine("    Insert: " + fileName);
            ostream.WriteLine("        To: " + GetID());

            RAFFileListEntry fileentry = this.GetDirectoryFile().GetFileList().GetFileEntry(fileName);

            if (fileentry == null)
            {
                //Define a new entry
                ostream.WriteLine("# Create new entry in RAF Archive, using experimental hash calculations");
                ostream.WriteLine("    Get DAT File Stream");
                FileStream datFileStream = GetDataFileContentStream();
                //navigate to the end of it, add the file.
                datFileStream.Seek(0, SeekOrigin.End);
                UInt32 offset = (UInt32)datFileStream.Length;

                byte[] finalContent;
                if (nocompress.Contains(fileName))
                {
                    finalContent = content;
                }
                else
                {
                    ostream.WriteLine("    Begin compression of content");
                    MemoryStream       mStream = new MemoryStream();
                    zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                    oStream.Write(content, 0, content.Length);
                    oStream.finish();
                    finalContent = mStream.ToArray();
                }

                ostream.WriteLine("    Begin DAT Write");
                datFileStream.Write(finalContent, 0, finalContent.Length);

                ostream.WriteLine("    Add file entry to in memory directory...");
                UInt32 strTableIndex = directoryFile.GetStringTable().Add(fileName);
                directoryFile.CreateFileEntry(fileName, offset, (UInt32)finalContent.Length, strTableIndex);
                //directoryFile.Save();
                //datFileStream.Close();
                ostream.WriteLine("    Done.");
                return(true);
            }
            else
            {
                //store the old offsets just in case we need to perform a restore.
                //This actually isn't necessary currently, since the raf directory file is saved
                //After packing.
                UInt32 oldOffset = (UInt32)fileentry.FileOffset;
                UInt32 oldSize   = (UInt32)fileentry.FileSize;
                ostream.WriteLine("Old Offset: " + oldOffset + "; Old Size: " + oldSize);

                ostream.WriteLine("Begin modify game files...  This may take a while");
                try
                {
                    ostream.WriteLine("    Get File Stream");
                    FileStream datFileStream = GetDataFileContentStream();
                    //navigate to the end of it, add the file.
                    datFileStream.Seek(0, SeekOrigin.End);
                    UInt32 offset = (UInt32)datFileStream.Length;

                    byte[] finalContent;
                    if (nocompress.Contains(fileName))
                    {
                        finalContent = content;
                    }
                    else
                    {
                        ostream.WriteLine("    Begin compression of content");
                        MemoryStream       mStream = new MemoryStream();
                        zlib.ZOutputStream oStream = new zlib.ZOutputStream(mStream, zlib.zlibConst.Z_DEFAULT_COMPRESSION); //using default compression level
                        oStream.Write(content, 0, content.Length);
                        oStream.finish();
                        finalContent = mStream.ToArray();
                    }

                    ostream.WriteLine("    Begin DAT Write");
                    datFileStream.Write(finalContent, 0, finalContent.Length);

                    ostream.WriteLine("    Begin FileEntry Write");
                    fileentry.FileOffset = offset;
                    fileentry.FileSize   = (UInt32)finalContent.Length;
                    //directoryFile.Save();

                    //datFileStream.Close();
                    ostream.WriteLine("    Done.");
                    return(true);
                }
                catch (Exception e)
                {
                    ostream.WriteLine("!! An error occurred in inserting a file.");
                    ostream.WriteLine("!! Note that the content of the raf archive has been added to");
                    ostream.WriteLine("!! But the directory file that points the game to the data in the content file");
                    ostream.WriteLine("!! Has not been modified.  In other words, if the game read the RAF archive now");
                    ostream.WriteLine("!! It wouldn't see a difference.");
                    ostream.WriteLine("!! However, the RAF archive is a bit bigger than before.");
                    ostream.WriteLine(e.ToString());

                    fileentry.FileOffset = oldOffset;
                    fileentry.FileSize   = oldSize;
                    //directoryFile.GetContent();
                    return(false);
                }
            }
        }