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; }
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; }
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); }
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; }
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; }
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; }