Пример #1
0
 /// <summary>
 /// <para>This constructor is used solely for extracting XML 
 /// data from a BAR file without leaving the XMB file sitting 
 /// around on the hard disk.</para>
 /// 
 /// <para>The method works by saving the file in its native
 /// XMB form, and then setting the class attributes to focus
 /// on extracting that file. Then the saveXMB method will
 /// extract from this temporary file, and once this class is
 /// disposed of and the destructor is called the temporary
 /// file will be deleted.</para>
 /// </summary>
 /// <param name="entry">The BAR file entry to be saved to XML.</param>
 /// <param name="saveDirectory">The directory to save the new XML 
 /// file to (leave blank for the same directory as the program).</param>
 public XMBReader(BarEntry entry, string saveDirectory)
 {
     // Set up instance variables...
     xmbFilePath = entry.fileName + ".tmp";
     xmlFilePath = saveDirectory + "\\" + entry.fileName.Substring(0, entry.fileName.LastIndexOf('.'));
     fileLength = 0;
     // Create a BarReader and save the file we need
     // to the temporary destination (as the XMB file)
     BarReader reader = new BarReader(entry.barFilePath);
     reader.saveFile(entry,xmbFilePath);
     // Set the temporary file flag
     isTemporaryFile = true;
 }
Пример #2
0
 /// <summary>
 /// Saves a file to program's location, this method
 /// works simply by calling the main saveFile method and
 /// specifying a blank string in place of the path.
 /// </summary>
 /// <param name="file">BarEntry object detailing the file to be saved</param>
 private void saveFile(BarEntry file)
 {
     saveFile(file, "");
 }
Пример #3
0
 /// <summary>
 /// The load method will load the BAR file that has been
 /// specified by the constructor. It returns a bool
 /// value specifying whether the operation has been
 /// successful.
 /// </summary>
 /// <returns>True if the BAR file has been loaded
 /// successfully, otherwise false.</returns>
 public bool load()
 {
     // We will be throwing exceptions about the
     // place, so we'd best try to be safe...
     try
     {
         // Does the BAR file even exist?
         if (!File.Exists(barFilePath))
             throw new Exception("BAR file does not exist!");
         // Declare some variables
         uint numFiles, filetableOffset, numRootFiles;
         int tempInt;
         string tempString, rootName;
         // Instantiate and open the filestream
         // to the bar file.
         input = new FileStream(barFilePath, FileMode.Open);
         // Now, start checking through the first
         // few bytes of the file to see if this is
         // a valid BAR file.
         // BAR files always start with a four byte string "ESPN"
         tempString = ByteReader.readString(input, 4);
         if (tempString != "ESPN")
             throw new Exception("'ESPN' not detected - Not a valid BAR file!");
         // Afterwards they feature a four byte integer value "2"
         tempInt = ByteReader.readInt(input, 4);
         if (tempInt != 2)
             throw new Exception("'2' not detected - Not a valid BAR file!");
         // Next they feature a four byte hex value of 0x44332211
         tempInt = ByteReader.readInt(input, 4);
         if (tempInt != 0x44332211)
             throw new Exception("'0x44332211' not detected - Not a valid BAR file!");
         // Lastly they always feature a large block of zero values
         bool allZeroes = true;
         for (int i = 0; i < 66; ++i)
         {
             tempInt = ByteReader.readInt(input, 4);
             if (tempInt != 0)
                 allZeroes = false;
         }
         if (!allZeroes)
             throw new Exception("Successive zeroes not detected - Not a valid BAR file!");
         // Unknown value - This is possibly a checksum, for
         // now however it is ignored.
         tempInt = ByteReader.readInt(input, 4);
         // Now the number of files stored within the BAR file
         // are located.
         numFiles = ByteReader.readUInt(input, 4);
         // Are there actually any files?
         if (numFiles == 0)
             throw new Exception("No files stored - This is an empty / invalid BAR file!");
         // Next is the offset for the file table, where the
         // contents of this BAR file are located.
         filetableOffset = ByteReader.readUInt(input, 4);
         // Is this actually a number?
         if (filetableOffset == 0)
             throw new Exception("File table offset blank - Not a valid BAR file!");
         // Now another 4 bytes of zeroes are located before
         // the actual data starts.
         tempInt = ByteReader.readInt(input, 4);
         if (tempInt != 0)
             throw new Exception("Zeroes not detected - Not a valid BAR file!");
         // If an exception has not been thrown thus far then
         // this is a valid BAR file and we can hopefully
         // proceed to the file table and start learning what
         // is locked inside!
         // Start by going to the location of the file table...
         input.Seek(filetableOffset, SeekOrigin.Begin);
         // Now we should be able to read the root name of this
         // BAR file.
         rootName = ByteReader.readFullString(input);
         // The number of files should also be listed here, get
         // it and check it matched the number of files given
         // earlier.
         numRootFiles = ByteReader.readUInt(input, 4);
         if (numRootFiles != numFiles)
             throw new Exception("File total mismatch - Not a valid BAR file!");
         // Now we can start looping throough the files in the
         // file table, saving their details in the files List.
         for (int fileIndex = 0; fileIndex < numFiles; fileIndex++)
         {
             // Create a new BAR Entry to take the data
             BarEntry file = new BarEntry();
             // Read in the offset for this file (its location
             // within the bar file)
             file.offset = ByteReader.readUInt(input, 4);
             // Check the file size for this file, it is
             // listed twice so compare the values are equal.
             uint length1 = ByteReader.readUInt(input, 4);
             uint length2 = ByteReader.readUInt(input, 4);
             // Only proceed if they are equal...
             if (length1 == length2)
             {
                 // This file is apparently valid, so
                 // store the length.
                 file.fileSize = length1;
                 // Now store the date information...
                 file.year = ByteReader.readUShort(input, 2);
                 file.month = ByteReader.readUShort(input, 2);
                 file.dayOfWeek = ByteReader.readUShort(input, 2);
                 file.day = ByteReader.readUShort(input, 2);
                 file.hour = ByteReader.readUShort(input, 2);
                 file.minute = ByteReader.readUShort(input, 2);
                 file.second = ByteReader.readUShort(input, 2);
                 file.msecond = ByteReader.readUShort(input, 2);
                 // If there's no data stored, as
                 // indicated with the 0xCCCC pattern,
                 // clear all date information.
                 if (file.year == 0xCCCC)
                     file.clearDate();
                 // Get the path of the file and set it
                 file.filePath = ByteReader.readFullString(input);
                 // Then set the full path of the BAR file
                 file.barFilePath = barFilePath;
                 // Lastly add this file to the List
                 files.Add(file);
             }
         }
         // Have we made it this far? We must have
         // been successful, return true.
         return true;
     }
     catch (Exception e)
     {
         // An error has occurred. Return false!
         return false;
     }
     finally
     {
         // Make sure that whatever happens the file
         // stream is closed!
         if (input != null)
             input.Close();
     }
 }
Пример #4
0
        /// <summary>
        /// Saves a file that is stored in the BAR file to an external file. The name
        /// and path for the file is specified by the file itself, however the root of that
        /// path can be defined by the user (or if left blank will be the directory the
        /// program is running).
        /// </summary>
        /// <param name="file">The BarEntry object detailing the file to be saved</param>
        /// <param name="savePath">The path where the item is to be saved (blank for the current directory)</param>
        public void saveFile(BarEntry file, string savePath)
        {
            // Could be doing some risky stuff here, so try...
            try
            {
                // Firstly, is the file parameter null?
                if (file == null)
                    throw new Exception("Supplied file was null - Could not save!");
                // Instantiate the input stream, opening the BAR
                // file specified in the barFilePath variable
                input = new FileStream(barFilePath, FileMode.Open);
                // Locate the file within the BAR file.
                input.Seek(file.offset, SeekOrigin.Begin);
                // Work out the full path of the file to be saved.
                string newPath = savePath;
                // Work out the directory path where the file is to be saved...
                string dirPath = newPath.Substring(0, newPath.LastIndexOf('\\') + 1);
                // ...Now check that the directories exist! If the
                // directories don't exist then the path must be created!
                // Of course, that's only if we *need* directories.
                if (dirPath != "")
                {
                    if (!Directory.Exists(dirPath))
                        Directory.CreateDirectory(dirPath);
                }
                // Now using a FileStream / BinaryWriter combo, write the data as it is
                // read from the BAR file to the new file (which will be overwritten if
                // it already exists, perhaps a bool check method could be used to make
                // sure the user doesn't overwrite something they've modded?)
                using (FileStream output = new FileStream(newPath, FileMode.Create))
                {
                    using (BinaryWriter writer = new BinaryWriter(output))
                    {
                        // How many bytes are left? Well currently all of them!
                        uint bytesRemaining = file.fileSize;
                        // Define a 128K buffer (this is what AoE3Ed uses and
                        // it seems to work perfectly).
                        uint bufferSize = 128 * 1024;
                        byte[] buffer = new byte[bufferSize];
                        // Now loop through the file as long as there are bytes
                        // remaining.
                        while (bytesRemaining > 0)
                        {
                            // If the buffer is still smaller than the file
                            // then use it as is, then remove the buffer size
                            // from bytes remaining. Otherwise resize the
                            // buffer and read only what is needed before
                            // setting the buffer to zero to end the loop.
                            if (bytesRemaining >= bufferSize)
                            {
                                input.Read(buffer, 0, (int)bufferSize);
                                bytesRemaining -= bufferSize;
                            }
                            else
                            {
                                buffer = new byte[bytesRemaining];
                                input.Read(buffer, 0, (int)bytesRemaining);
                                bytesRemaining = 0;
                            }
                            // Write the contents of the buffer to the file!
                            writer.Write(buffer);
                        }
                        // Once we're finished we need to close the writer.
                        writer.Close();
                    }
                }

            }
            catch (Exception e)
            {
                // Have we caught an exception? Tell the user
                // about it...
                Console.Out.WriteLine(e.StackTrace);
            }
            finally
            {
                // Ensure the input is closed
                input.Close();
            }
        }