Example #1
0
        static void Extract( FileStream file, String destination, Dictionary<uint, string> filenameHashDict = null )
        {
            System.IO.Directory.CreateDirectory( destination );

            uint magic = file.ReadUInt32();
            uint filecount = file.ReadUInt32();

            var FileInfos = new S2ARHeaderFileInfo[filecount];
            for ( int i = 0; i < filecount; ++i ) {
                FileInfos[i] = new S2ARHeaderFileInfo();
                FileInfos[i].Hash = file.ReadUInt32();
                FileInfos[i].Filesize = file.ReadUInt32();
            }

            for ( int i = 0; i < filecount; ++i ) {
                string filename;
                if ( filenameHashDict != null && filenameHashDict.ContainsKey( FileInfos[i].Hash ) ) {
                    filename = System.IO.Path.Combine( destination, filenameHashDict[FileInfos[i].Hash] );
                } else {
                    filename = System.IO.Path.Combine( destination, i.ToString( "D4" ) + Util.GuessFileExtension( file ) );
                }
                FileStream newFile = new FileStream( filename, FileMode.Create );
                Util.CopyStream( file, newFile, (int)FileInfos[i].Filesize );
                newFile.Close();
            }

            return;
        }
Example #2
0
        public static int Execute( List<string> args )
        {
            if ( args.Count == 0 ) {
                Console.WriteLine( "This is intended to help extracting skit audio from the Xbox 360 game files." );
                Console.WriteLine( "Do the following in order:" );
                Console.WriteLine( "-- unpack chat.svo (FPS4 archive, with HyoutaTools -> ToVfps4e)" );
                Console.WriteLine( "-- decompress individual skit with xbdecompress" );
                Console.WriteLine( "-- unpack skit (FPS4 archive, with HyoutaTools -> ToVfps4e)" );
                Console.WriteLine( "-- cut SE3 header from audio file to get a nub archive" );
                Console.WriteLine( "   (file 0004, seems to be 0x800 bytes for skits but can be bigger, first four bytes of new file should be 0x00020100)" );
                Console.WriteLine( "-- extract nub archive with NUBExt r12beta" );
                Console.WriteLine( "-- this gives you an \"xma\" file that isn't actually an xma, run this tool on it" );
                Console.WriteLine( "-- resulting file is a valid enough xma file that can be converted to WAV with \"toWav\"" );
                return -1;
            }

            string filename = args[0];
            using ( var source = new FileStream( filename, FileMode.Open ) ) {
                using ( var dest = new FileStream( filename + "-real.xma", FileMode.Create ) ) {
                    source.Position = 0x100;
                    int dataLength = (int)( source.Length - source.Position );

                    dest.WriteAscii( "RIFF" );
                    dest.WriteUInt32( (uint)dataLength + 0x34 );
                    dest.WriteAscii( "WAVE" );
                    dest.WriteAscii( "fmt " );

                    dest.WriteUInt32( 0x20 );

                    source.Position = 0xBC;
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );
                    dest.WriteByte( (byte)source.ReadByte() );
                    dest.WriteByte( (byte)source.ReadByte() );
                    dest.WriteUInt32( source.ReadUInt32().SwapEndian() );
                    dest.WriteUInt32( source.ReadUInt32().SwapEndian() );
                    dest.WriteUInt32( source.ReadUInt32().SwapEndian() );
                    dest.WriteUInt32( source.ReadUInt32().SwapEndian() );
                    dest.WriteByte( (byte)source.ReadByte() );
                    dest.WriteByte( (byte)source.ReadByte() );
                    dest.WriteUInt16( source.ReadUInt16().SwapEndian() );

                    dest.WriteAscii( "data" );
                    dest.WriteUInt32( (uint)dataLength );

                    source.Position = 0x100;
                    Util.CopyStream( source, dest, dataLength );
                }
            }

            return 0;
        }
Example #3
0
        public static bool Export(string originalScriptFilename, string databaseFilename, string gracesJapaneseFilename, string newScriptFilename)
        {
            byte[] script = System.IO.File.ReadAllBytes(originalScriptFilename);
            uint   sectionPointerLocation = BitConverter.ToUInt32(script, 0);

            // this is SUPER HACKY but should work
            using (var stream = new System.IO.FileStream(newScriptFilename, System.IO.FileMode.Create)) {
                var entries = GraceNoteDatabaseEntry.GetAllEntriesFromDatabase("Data Source=" + databaseFilename, "Data Source=" + gracesJapaneseFilename);

                // copy whole flie except for the section pointers
                for (int i = 0; i < sectionPointerLocation; ++i)
                {
                    stream.WriteByte(script[i]);
                }

                long pos = stream.Position;
                // remove original strings from the file
                foreach (var entry in entries)
                {
                    stream.Position = entry.PointerRef;
                    RemoveString(stream, stream.ReadUInt32());
                }
                stream.Position = pos;

                // now write the modified strings from the GN db at the end of the file
                foreach (var entry in entries)
                {
                    uint stringLocation = Convert.ToUInt32(stream.Position);
                    stream.Position = entry.PointerRef;
                    stream.WriteUInt32(stringLocation);
                    stream.Position = stringLocation;
                    stream.Write(StringToBytesBlazeUnion(entry.TextEN));
                    stream.WriteByte(0);
                }

                // write the section pointers and replace position
                stream.Position = stream.Position.Align(4);
                uint newSectionPointerLocation = Convert.ToUInt32(stream.Position);
                for (uint i = sectionPointerLocation; i < script.Length; ++i)
                {
                    stream.WriteByte(script[i]);
                }
                stream.Position = 0;
                stream.WriteUInt32(newSectionPointerLocation);
            }

            return(true);
        }
Example #4
0
        public static bool Export( string originalScriptFilename, string databaseFilename, string gracesJapaneseFilename, string newScriptFilename )
        {
            byte[] script = System.IO.File.ReadAllBytes( originalScriptFilename );
            uint sectionPointerLocation = BitConverter.ToUInt32( script, 0 );

            // this is SUPER HACKY but should work
            using ( var stream = new System.IO.FileStream( newScriptFilename, System.IO.FileMode.Create ) ) {
                var entries = GraceNoteDatabaseEntry.GetAllEntriesFromDatabase( "Data Source=" + databaseFilename, "Data Source=" + gracesJapaneseFilename );

                // copy whole flie except for the section pointers
                for ( int i = 0; i < sectionPointerLocation; ++i ) {
                    stream.WriteByte( script[i] );
                }

                long pos = stream.Position;
                // remove original strings from the file
                foreach ( var entry in entries ) {
                    stream.Position = entry.PointerRef;
                    RemoveString( stream, stream.ReadUInt32() );
                }
                stream.Position = pos;

                // now write the modified strings from the GN db at the end of the file
                foreach ( var entry in entries ) {
                    uint stringLocation = Convert.ToUInt32( stream.Position );
                    stream.Position = entry.PointerRef;
                    stream.WriteUInt32( stringLocation );
                    stream.Position = stringLocation;
                    stream.Write( StringToBytesBlazeUnion( entry.TextEN ) );
                    stream.WriteByte( 0 );
                }

                // write the section pointers and replace position
                stream.Position = stream.Position.Align( 4 );
                uint newSectionPointerLocation = Convert.ToUInt32( stream.Position );
                for ( uint i = sectionPointerLocation; i < script.Length; ++i ) {
                    stream.WriteByte( script[i] );
                }
                stream.Position = 0;
                stream.WriteUInt32( newSectionPointerLocation );
            }

            return true;
        }
Example #5
0
        private bool LoadFile( string headerFilename, string contentFilename = null )
        {
            try {
                infile = new FileStream( headerFilename, FileMode.Open );
                if ( contentFilename != null ) {
                    contentFile = new FileStream( contentFilename, FileMode.Open );
                } else {
                    contentFile = infile;
                }
            } catch ( Exception ) {
                Console.WriteLine( "ERROR: can't open " + headerFilename );
                return false;
            }

            infile.Seek( 0x00, SeekOrigin.Begin );
            string magic = infile.ReadAscii( 4 );
            if ( magic != "FPS4" ) {
                Console.WriteLine( "Not an FPS4 file!" );
                return false;
            }

            Endian = Util.Endianness.BigEndian;
            FileCount = infile.ReadUInt32().FromEndian( Endian );
            HeaderSize = infile.ReadUInt32().FromEndian( Endian );

            // if header seems huge then we probably have assumed the wrong endianness
            if ( HeaderSize > 0xFFFF ) {
                Endian = Util.Endianness.LittleEndian;
                FileCount = FileCount.ToEndian( Util.Endianness.BigEndian ).FromEndian( Endian );
                HeaderSize = HeaderSize.ToEndian( Util.Endianness.BigEndian ).FromEndian( Endian );
            }

            FirstFileStart = infile.ReadUInt32().FromEndian( Endian );
            EntrySize = infile.ReadUInt16().FromEndian( Endian );
            ContentBitmask = infile.ReadUInt16().FromEndian( Endian );
            Unknown2 = infile.ReadUInt32().FromEndian( Endian );
            ArchiveNameLocation = infile.ReadUInt32().FromEndian( Endian );
            infile.Position = ArchiveNameLocation;
            if ( ArchiveNameLocation > 0 ) {
                ArchiveName = infile.ReadShiftJisNullterm();
            }

            Alignment = FirstFileStart;

            Console.WriteLine( "Content Bitmask: 0x" + ContentBitmask.ToString( "X4" ) );

            return true;
        }
Example #6
0
        public static int Execute( List<string> args )
        {
            if ( args.Count != 4 ) {
                Console.WriteLine( "Usage: OldTOFHDB Folder NewTLDAT NewTOFHDB" );
                return -1;
            }

            String OldTOFHDB = args[0];
            String ExtractFolder = args[1];
            String TLDAT = args[2];
            String TOFHDB = args[3];
            TOFHDBheader header = new TOFHDBheader( OldTOFHDB );

            // collect files
            SortedDictionary<uint, string> filenameMap = new SortedDictionary<uint, string>();
            foreach ( string dir in Directory.EnumerateDirectories( ExtractFolder ) ) {
                foreach ( string file in Directory.EnumerateFiles( dir ) ) {
                    string filenumstr = Path.GetFileNameWithoutExtension( file );
                    uint num = Util.ParseDecOrHex( filenumstr );
                    filenameMap.Add( num, file );
                }
            }

            if ( filenameMap.Count != header.FileArray.Count ) {
                Console.WriteLine( "File count mismatch!" );
                return 1;
            }
            if ( filenameMap.First().Key != 1 || filenameMap.Last().Key != header.FileArray.Count ) {
                Console.WriteLine( "Filenames are wrong!" );
                return 2;
            }

            // write files and populate header
            using ( FileStream fsData = File.Open( TLDAT, FileMode.Create, FileAccess.ReadWrite ) ) {
                foreach ( var f in filenameMap ) {
                    using ( FileStream fs = new FileStream( f.Value, FileMode.Open ) ) {
                        header.FileArray[(int)( f.Key - 1 )].Filesize = (ulong)fs.Length;
                        header.FileArray[(int)( f.Key - 1 )].CompressedSize = (ulong)fs.Length;
                        header.FileArray[(int)( f.Key - 1 )].Offset = (ulong)fsData.Position;

                        // check if TLZC compressed and write uncompressed size if so
                        if ( fs.PeekUInt32() == 0x435A4C54 ) {
                            fs.DiscardBytes( 12 );
                            header.FileArray[(int)( f.Key - 1 )].Filesize = fs.ReadUInt32();
                            fs.Position = 0;
                        }

                        fs.CopyTo( fsData );
                        fs.Close();
                    }
                }
                fsData.Close();
            }

            // write header
            using ( FileStream fs = new FileStream( TOFHDB, FileMode.Create, FileAccess.ReadWrite ) ) {
                header.Write( fs );
                fs.Close();
            }

            return 0;
        }