Exemple #1
0
        private static int DoWork(Options options, DecodeParams baseDecodeParams)
        {
            var fileInfo           = new FileInfo(options.InputFileName);
            var baseExtractDirPath = Path.Combine(fileInfo.DirectoryName ?? string.Empty, string.Format(DirTemplate, fileInfo.Name));

            if (!Directory.Exists(baseExtractDirPath))
            {
                Directory.CreateDirectory(baseExtractDirPath);
            }

            using (var acb = AcbFile.FromFile(options.InputFileName)) {
                var formatVersion = acb.FormatVersion;

                if (acb.InternalAwb != null)
                {
                    var internalDirPath = Path.Combine(baseExtractDirPath, "internal");

                    ProcessAllBinaries(formatVersion, baseDecodeParams, internalDirPath, acb.InternalAwb, acb.Stream, true);
                }

                if (acb.ExternalAwb != null)
                {
                    var externalDirPath = Path.Combine(baseExtractDirPath, "external");

                    using (var fs = File.Open(acb.ExternalAwb.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        ProcessAllBinaries(formatVersion, baseDecodeParams, externalDirPath, acb.ExternalAwb, fs, false);
                    }
                }
            }

            return(0);
        }
Exemple #2
0
        public List <IUndoRedo> PasteCues()
        {
            List <IUndoRedo> undos = new List <IUndoRedo>();

            if (!CanPasteCues())
            {
                return(undos);
            }

            ACB_File tempAcb = ACB_File.LoadFromClipboard();

            //Check if cues exist in current ACB. If they do, then generate new GUIDs for them (duplication mode)
            if (AcbFile.Cues.Any(x => tempAcb.Cues.Any(y => y.InstanceGuid == x.InstanceGuid)))
            {
                tempAcb.NewInstanceGuids();
            }

            foreach (var cue in tempAcb.Cues)
            {
                undos.AddRange(AcbFile.CopyCue((int)cue.ID, tempAcb));
            }

            Refresh();
            undos.Add(new UndoActionDelegate(this, "Refresh", true));
            return(undos);
        }
Exemple #3
0
        private static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: AcbUnzip <Input ACB File>");
                return;
            }
            var fileName = args[0];
            var fileInfo = new FileInfo(fileName);

            var fullDirPath = Path.Combine(fileInfo.DirectoryName ?? string.Empty, string.Format(DirTemplate, fileInfo.Name));

            if (!Directory.Exists(fullDirPath))
            {
                Directory.CreateDirectory(fullDirPath);
            }

            using (var acb = AcbFile.FromFile(fileName)) {
                var fileNames = acb.GetFileNames();
                foreach (var s in fileNames)
                {
                    var extractName = Path.Combine(fullDirPath, s);
                    using (var fs = new FileStream(extractName, FileMode.Create, FileAccess.Write)) {
                        using (var source = acb.OpenDataStream(s)) {
                            WriteFile(source, fs);
                        }
                    }
                    Console.WriteLine(s);
                }
            }
        }
Exemple #4
0
        public void UndoableRandomizeCueIds()
        {
            var undos = AcbFile.RandomizeCueIds();

            Refresh();
            undos.Add(new UndoActionDelegate(this, nameof(Refresh), true));
            UndoManager.Instance.AddUndo(new CompositeUndo(undos, "Randomize Cue IDs"));
        }
Exemple #5
0
        private static void ProcessAllBinaries(uint acbFormatVersion, DecodeParams baseDecodeParams, string extractDir, Afs2Archive archive, Stream dataStream, bool isInternal)
        {
            if (!Directory.Exists(extractDir))
            {
                Directory.CreateDirectory(extractDir);
            }

            var afsSource    = isInternal ? "internal" : "external";
            var decodeParams = baseDecodeParams;

            if (acbFormatVersion >= NewEncryptionVersion)
            {
                decodeParams.KeyModifier = archive.HcaKeyModifier;
            }
            else
            {
                decodeParams.KeyModifier = 0;
            }

            foreach (var entry in archive.Files)
            {
                var record          = entry.Value;
                var extractFileName = AcbFile.GetSymbolicFileNameFromCueId(record.CueId);

                extractFileName = extractFileName.ReplaceExtension(".bin", ".wav");

                var extractFilePath = Path.Combine(extractDir, extractFileName);

                using (var fileData = AcbHelper.ExtractToNewStream(dataStream, record.FileOffsetAligned, (int)record.FileLength)) {
                    var isHcaStream = HcaReader.IsHcaStream(fileData);

                    Console.Write("Processing {0} AFS: #{1} (offset={2} size={3})...   ", afsSource, record.CueId, record.FileOffsetAligned, record.FileLength);

                    if (isHcaStream)
                    {
                        try {
                            using (var fs = File.Open(extractFilePath, FileMode.Create, FileAccess.Write, FileShare.Write)) {
                                DecodeHca(fileData, fs, decodeParams);
                            }

                            Console.WriteLine("decoded");
                        } catch (Exception ex) {
                            if (File.Exists(extractFilePath))
                            {
                                File.Delete(extractFilePath);
                            }

                            Console.WriteLine(ex.Message);
                        }
                    }
                    else
                    {
                        Console.WriteLine("skipped (not HCA)");
                    }
                }
            }
        }
        private async void CopyCues()
        {
            List <Cue_Wrapper> selectedCues = dataGrid.SelectedItems.Cast <Cue_Wrapper>().ToList();

            if (selectedCues != null)
            {
                AcbFile.CopyCues(selectedCues);
            }
        }
Exemple #7
0
        private static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: AcbUnzip <Input ACB File>");
                return;
            }
            var fileName = args[0];
            var fileInfo = new FileInfo(fileName);

            var baseExtractDirPath = Path.Combine(fileInfo.DirectoryName ?? string.Empty, string.Format(DirTemplate, fileInfo.Name));

            if (!Directory.Exists(baseExtractDirPath))
            {
                Directory.CreateDirectory(baseExtractDirPath);
            }

            using (var acb = AcbFile.FromFile(fileName)) {
                var archivedEntryNames = acb.GetFileNames();

                for (var i = 0; i < archivedEntryNames.Length; ++i)
                {
                    var isCueNonEmpty = archivedEntryNames[i] != null;
                    var s             = archivedEntryNames[i] ?? AcbFile.GetSymbolicFileNameFromCueId((uint)i);
                    var extractName   = Path.Combine(baseExtractDirPath, s);

                    try {
                        using (var source = isCueNonEmpty ? acb.OpenDataStream(s) : acb.OpenDataStream((uint)i)) {
                            using (var fs = new FileStream(extractName, FileMode.Create, FileAccess.Write, FileShare.Write)) {
                                WriteFile(source, fs);
                            }
                        }

                        Console.WriteLine("Extracted from cue: {0}", s);
                    } catch (Exception ex) {
                        PrintColoredErrorMessage(ex.Message);
                    }
                }

                if (acb.InternalAwb != null)
                {
                    var internalDirPath = Path.Combine(baseExtractDirPath, "internal");

                    ExtractAllBinaries(internalDirPath, acb.InternalAwb, acb.Stream, true);
                }

                if (acb.ExternalAwb != null)
                {
                    var externalDirPath = Path.Combine(baseExtractDirPath, "external");

                    using (var fs = File.Open(acb.ExternalAwb.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                        ExtractAllBinaries(externalDirPath, acb.ExternalAwb, fs, false);
                    }
                }
            }
        }
 private bool CanPasteOnCue()
 {
     if (!IsCueSelected() || !IsFileLoaded())
     {
         return(false);
     }
     if (AcbFile.CanPasteCues() || AcbFile.CanPasteAction() || AcbFile.CanPasteTrack())
     {
         return(true);
     }
     return(false);
 }
Exemple #9
0
        static void Main(string[] args)
        {
            Console.WriteLine("ACB Tool by CaptainSwag101\n" +
                              "Version 1.0.0, built on 2020-08-03\n");

            if (args.Length != 2)
            {
                Console.WriteLine("ERROR: Invalid number of parameters. Please provide only an ACB and AWB path, respectively.");
                return;
            }

            AcbFile loadedAcb     = new AcbFile();
            string  loadedAcbPath = args[0];

            loadedAcb.Load(loadedAcbPath);

            AwbFile loadedAwb     = new AwbFile();
            string  loadedAwbPath = args[1];

            loadedAwb.Load(loadedAwbPath);

            FileInfo info      = new FileInfo(loadedAcbPath);
            string   outputDir = info.DirectoryName + Path.DirectorySeparatorChar + info.Name.Substring(0, info.Name.Length - info.Extension.Length);

            Directory.CreateDirectory(outputDir);

            //using FileStream fs = new FileStream(info.FullName + "_cuenames.txt", FileMode.Create);
            foreach (var cue in loadedAcb.Cues)
            {
                //fs.Write(Encoding.ASCII.GetBytes(cue.Value + '\n'));

                short audioKey = (short)loadedAcb.Cues.Keys.ToList().IndexOf(cue.Key);
                if (loadedAwb.AudioData.ContainsKey(audioKey))
                {
                    string outFilePath = outputDir + Path.DirectorySeparatorChar + cue.Value;
                    byte[] audioData   = loadedAwb.AudioData[audioKey];

                    // Guess output file extension
                    if (audioData[0] == 0x80 && audioData[1] == 0x00)
                    {
                        outFilePath += ".adx";
                    }
                    else if (audioData[0] == (byte)'H' && audioData[1] == (byte)'C' && (char)audioData[2] == (byte)'A')
                    {
                        outFilePath += ".hca";
                    }

                    using FileStream audioFile = new FileStream(outFilePath, FileMode.Create);
                    audioFile.Write(audioData);
                }
            }
            //fs.Flush();
        }
        private LiveMusicWaveStream(Stream acbStream, string acbFileName, DecodeParams decodeParams)
        {
            _acb = AcbFile.FromStream(acbStream, acbFileName, false);
            var names = _acb.GetFileNames();

            _internalName  = names[0];
            _hcaDataStream = _acb.OpenDataStream(_internalName);
            var hcaWaveStream = new HcaAudioStream(_hcaDataStream, decodeParams);

            _waveStream   = new WaveFileReader(hcaWaveStream);
            _sourceStream = acbStream;
            _syncObject   = new object();
        }
Exemple #11
0
        private static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Usage: AcbUnzip <Input ACB File>");
                return;
            }
            var fileName = args[0];
            var fileInfo = new FileInfo(fileName);

            var fullDirPath = Path.Combine(fileInfo.DirectoryName, string.Format(DirTemplate, fileInfo.Name));

            if (!Directory.Exists(fullDirPath))
            {
                Directory.CreateDirectory(fullDirPath);
            }

            using (var acb = AcbFile.FromFile(fileName)) {
                var archivedEntryNames = acb.GetFileNames();
                for (var i = 0; i < archivedEntryNames.Length; ++i)
                {
                    var isCueNonEmpty = archivedEntryNames[i] != null;
                    var s             = archivedEntryNames[i] ?? AcbFile.GetSymbolicFileNameFromCueId((uint)i);
                    var extractName   = Path.Combine(fullDirPath, s);
                    try {
                        using (var source = isCueNonEmpty ? acb.OpenDataStream(s) : acb.OpenDataStream((uint)i)) {
                            using (var fs = new FileStream(extractName, FileMode.Create, FileAccess.Write)) {
                                WriteFile(source, fs);
                            }
                        }
                        Console.WriteLine(s);
                    } catch (Exception ex) {
                        var origForeground = ConsoleColor.Gray;
                        try {
                            origForeground = Console.ForegroundColor;
                        } catch {
                        }
                        try {
                            Console.ForegroundColor = ConsoleColor.Red;
                        } catch {
                        }
                        Console.WriteLine(ex.Message);
                        try {
                            Console.ForegroundColor = origForeground;
                        } catch {
                        }
                    }
                }
            }
        }
        //File Drop (messy duplication, for now...)
        private async void DataGrid_Drop(object sender, DragEventArgs e)
        {
            e.Handled = true;
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] droppedFilePaths = e.Data.GetData(DataFormats.FileDrop, true) as string[];

                    foreach (string droppedFile in droppedFilePaths)
                    {
                        switch (System.IO.Path.GetExtension(droppedFile))
                        {
                        case ".wav":
                        case ".mp3":
                        case ".wma":
                        case ".aac":
                        case ".hca":
                            AddCueForm form = new AddCueForm(Application.Current.MainWindow, droppedFile, true);

                            while (!form.IsDone)
                            {
                                await Task.Delay(50);
                            }

                            if (form.Finished)
                            {
                                if (form.AddTrack)
                                {
                                    AcbFile.UndoableAddCue(form.CueName, form.ReferenceType, form.HcaBytes, form.Streaming, form.Loop, false);
                                }
                                else
                                {
                                    AcbFile.UndoableAddCue(form.CueName, form.ReferenceType, false);
                                }
                            }
                            break;

                        default:
                            MessageBox.Show(String.Format("The filetype of the dropped file ({0}) is not supported.", System.IO.Path.GetExtension(droppedFilePaths[0])), "File Drop", MessageBoxButton.OK, MessageBoxImage.Error);
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("The dropped file could not be opened.\n\nThe reason given by the system: {0}", ex.Message), "File Drop", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
 private async void PasteCues()
 {
     if (Clipboard.ContainsData(ACB_File.CLIPBOARD_ACB_CUES))
     {
         AcbFile.UndoablePasteCues();
     }
     else if (Clipboard.ContainsData(ACB_File.CLIPBOARD_ACB_TRACK))
     {
         AcbFile.UndoablePasteTrack(GetSelectedCue());
     }
     else if (Clipboard.ContainsData(ACB_File.CLIPBOARD_ACB_ACTION))
     {
         AcbFile.UndoablePasteAction(GetSelectedCue());
     }
 }
Exemple #14
0
        static void Main(string[] args)
        {
            AcbFile loadedAcb     = new AcbFile();
            string  loadedAcbPath = @"D:\Games\Persona Modding\AcbEditor\bgm.acb";

            //string loadedAcbPath = @"D:\Games\SteamLibrary\steamapps\common\Danganronpa V3 Killing Harmony\data\win\game_resident\game_resident\JINGLE.acb";
            //string loadedAcbPath = @"D:\Games\SteamLibrary\steamapps\common\Danganronpa V3 Killing Harmony\data\win\game_resident\voice_resident_ENG\VOICE_ENG.acb";
            loadedAcb.Load(loadedAcbPath);

            AwbFile loadedAwb     = new AwbFile();
            string  loadedAwbPath = @"D:\Games\Persona Modding\AcbEditor\bgm.awb";

            //string loadedAwbPath = @"D:\Games\SteamLibrary\steamapps\common\Danganronpa V3 Killing Harmony\data\win\sound\JINGLE.awb";
            //string loadedAwbPath = @"D:\Games\SteamLibrary\steamapps\common\Danganronpa V3 Killing Harmony\data\win\sound\VOICE_ENG.awb";
            loadedAwb.Load(loadedAwbPath);

            FileInfo info      = new FileInfo(loadedAcbPath);
            string   outputDir = info.DirectoryName + Path.DirectorySeparatorChar + info.Name.Substring(0, info.Name.Length - info.Extension.Length);

            Directory.CreateDirectory(outputDir);

            foreach (var cue in loadedAcb.Cues)
            {
                if (loadedAwb.AudioData.ContainsKey((short)loadedAcb.Cues.Keys.ToList().IndexOf(cue.Key)))
                {
                    string outFilePath = outputDir + Path.DirectorySeparatorChar + cue.Value;
                    byte[] audioData   = loadedAwb.AudioData[(short)loadedAcb.Cues.Keys.ToList().IndexOf(cue.Key)];

                    // Guess output file extension
                    if (audioData[0] == 0x80 && audioData[1] == 0x00)
                    {
                        outFilePath += ".adx";
                    }
                    else if (audioData[0] == (byte)'H' && audioData[1] == (byte)'C' && (char)audioData[2] == (byte)'A')
                    {
                        outFilePath += ".hca";
                    }

                    using FileStream audioFile = new FileStream(outFilePath, FileMode.Create);
                    audioFile.Write(audioData);
                }
            }
        }
 public static bool Check(Stream stream, string acbFileName, string hcaName)
 {
     try {
         using (var acb = AcbFile.FromStream(stream, acbFileName, false)) {
             if (!acb.FileExists(hcaName))
             {
                 return(false);
             }
             try {
                 using (var acbStream = acb.OpenDataStream(hcaName)) {
                     return(HcaDecoder.IsHcaStream(acbStream));
                 }
             } catch (HcaException) {
                 return(false);
             }
         }
     } catch (Exception) {
         return(false);
     }
 }
Exemple #16
0
        public List <IUndoRedo> PasteAction(Cue_Wrapper cue)
        {
            List <IUndoRedo> undos = new List <IUndoRedo>();

            if (!CanPasteAction())
            {
                return(undos);
            }

            CopiedAction action = (CopiedAction)Clipboard.GetData(ACB_File.CLIPBOARD_ACB_ACTION);

            if (action != null && cue != null)
            {
                undos.AddRange(AcbFile.AddActionToCue(cue.CueRef, action));
            }

            cue.Refresh();
            undos.Add(new UndoActionDelegate(cue, "Refresh", true));

            return(undos);
        }
Exemple #17
0
        public List <IUndoRedo> PasteTrack(Cue_Wrapper cue)
        {
            List <IUndoRedo> undos = new List <IUndoRedo>();

            if (!CanPasteTrack())
            {
                return(undos);
            }

            CopiedTrack track = (CopiedTrack)Clipboard.GetData(ACB_File.CLIPBOARD_ACB_TRACK);

            if (track != null && cue != null)
            {
                undos.AddRange(AcbFile.AddTrackToCue(cue.CueRef, track.TrackBytes, track.Streaming, track.Loop, track.encodeType));
            }

            cue.Refresh();
            undos.Add(new UndoActionDelegate(cue, "Refresh", true));

            return(undos);
        }
Exemple #18
0
        public List <IUndoRedo> AddCue(string name, ReferenceType type, byte[] trackBytes, bool streaming, bool loop, bool is3Dsound, EncodeType encodeType, out int cueId)
        {
            List <IUndoRedo> undos = new List <IUndoRedo>();

            ACB_Cue acbCue;

            undos.AddRange(AcbFile.AddCue(name, type, trackBytes, streaming, loop, encodeType, out acbCue));

            if (is3Dsound)
            {
                AcbFile.Add3dDefToCue(acbCue);
            }

            Cue_Wrapper wrapper = new Cue_Wrapper(acbCue, this);

            Cues.Add(wrapper);
            undos.Add(new UndoableListAdd <Cue_Wrapper>(Cues, wrapper, ""));
            undos.Add(GetRefreshDelegate());

            cueId = (int)acbCue.ID;
            return(undos);
        }
        private async void AddNewCue()
        {
            AddCueForm form = new AddCueForm(Application.Current.MainWindow, string.Format("cue_{0}", AcbFile.AcbFile.GetFreeCueId()));

            form.ShowDialog();

            while (!form.IsDone)
            {
                await Task.Delay(50);
            }

            if (form.Finished)
            {
                if (form.AddTrack)
                {
                    AcbFile.UndoableAddCue(form.CueName, form.ReferenceType, form.HcaBytes, form.Streaming, form.Loop, form.Is3DSound);
                }
                else
                {
                    AcbFile.UndoableAddCue(form.CueName, form.ReferenceType, form.Is3DSound);
                }
            }
        }
Exemple #20
0
        private static void ExtractAllBinaries(string extractDir, Afs2Archive archive, Stream dataStream, bool isInternal)
        {
            if (!Directory.Exists(extractDir))
            {
                Directory.CreateDirectory(extractDir);
            }

            var afsSource = isInternal ? "internal" : "external";

            foreach (var entry in archive.Files)
            {
                var record          = entry.Value;
                var extractFileName = AcbFile.GetSymbolicFileNameFromCueId(record.CueId);
                var extractFilePath = Path.Combine(extractDir, extractFileName);

                using (var fs = File.Open(extractFilePath, FileMode.Create, FileAccess.Write, FileShare.Write)) {
                    using (var fileData = AcbHelper.ExtractToNewStream(dataStream, record.FileOffsetAligned, (int)record.FileLength)) {
                        WriteFile(fileData, fs);
                    }
                }

                Console.WriteLine("Extracted from {0} AFS: #{1} (offset={2} size={3})", afsSource, record.CueId, record.FileOffsetAligned, record.FileLength);
            }
        }
Exemple #21
0
 private async void RandomizeCueIDs()
 {
     AcbFile.UndoableRandomizeCueIds();
 }
        private async void DeleteCue()
        {
            List <Cue_Wrapper> selectedCues = dataGrid.SelectedItems.Cast <Cue_Wrapper>().ToList();

            AcbFile.UndoableDeleteCues(selectedCues);
        }
Exemple #23
0
        // ReSharper disable once IdentifierTypo
        public static List <string> AcbToWavs(FileInfo source, DirectoryInfo dest)
        {
            var res = new List <string>();

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            const uint newEncryptionVersion = 0x01300000;

            var acb = AcbFile.FromFile(source.FullName);

            var acbFormatVersion = acb.FormatVersion;

            if (acb.ExternalAwb != null)
            {
                var awb          = acb.ExternalAwb;
                var decodeParams = DecodeParams.CreateDefault(
                    0x0030D9E8, 0,
                    acbFormatVersion >= newEncryptionVersion ? awb.HcaKeyModifier : (ushort)0);

                foreach (var entry in awb.Files)
                {
                    var record   = entry.Value;
                    var cueName  = acb.Cues.FirstOrDefault(x => x.CueId == record.CueId)?.CueName;
                    var fileName = cueName == null
                        ? Path.GetFileNameWithoutExtension(source.Name) + record.CueId.ToString("D3")
                        : Path.GetFileNameWithoutExtension(cueName);

                    var extractFileName  = Path.Combine(dest.FullName, fileName + ".wav");
                    var guessAwbFullName = Path.Combine(source.DirectoryName ?? ".", awb.FileName);

                    if (source.DirectoryName != null && File.Exists(guessAwbFullName))
                    {
                        AfsToWav(record, File.OpenRead(guessAwbFullName), decodeParams, extractFileName);
                    }
                    else if (File.Exists(awb.FileName))
                    {
                        AfsToWav(record, File.OpenRead(awb.FileName), decodeParams, extractFileName);
                    }
                    else
                    {
                        throw new FileNotFoundException($"Awb file not found, skip {source}", awb.FileName);
                    }

                    res.Add(extractFileName);
                }
            }

            if (acb.InternalAwb != null)
            {
                var awb          = acb.InternalAwb;
                var decodeParams = DecodeParams.CreateDefault(
                    0x0030D9E8, 0,
                    acbFormatVersion >= newEncryptionVersion ? awb.HcaKeyModifier : (ushort)0);

                foreach (var entry in awb.Files)
                {
                    var record          = entry.Value;
                    var extractFileName = Path.Combine(dest.FullName,
                                                       Path.GetFileNameWithoutExtension(source.Name) + $"_{record.CueId:D3}.wav");
                    AfsToWav(record, acb.Stream, decodeParams, extractFileName);

                    res.Add(extractFileName);
                }
            }

            return(res);
        }