mirror of
https://github.com/blueskythlikesclouds/SonicAudioTools.git
synced 2025-02-13 09:12:35 +01:00
212 lines
7.3 KiB
C#
212 lines
7.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using SonicAudioLib.CriMw;
|
|
using SonicAudioLib.Archives;
|
|
using System.IO;
|
|
|
|
using HedgeEdit.UI;
|
|
|
|
namespace AcbInjector
|
|
{
|
|
class Program
|
|
{
|
|
static List<FileInfo> Junk = new List<FileInfo>();
|
|
|
|
[STAThread]
|
|
static void Main(string[] args)
|
|
{
|
|
Application.EnableVisualStyles();
|
|
|
|
if (args.Length < 1)
|
|
{
|
|
MessageBox.Show("This program can inject audio files into ACB files without the need of repacking their AWBs.\n\nTo start, drag and drop an ACB file to the executable.", "ACB Injector", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
string sourceFileName = null;
|
|
string sourceAudioFileName = null;
|
|
int waveformId = -1;
|
|
string destinationFileName = null;
|
|
|
|
foreach (var arg in args)
|
|
{
|
|
if (int.TryParse(arg, out int ret) && waveformId < 0)
|
|
{
|
|
waveformId = ret;
|
|
}
|
|
|
|
else if (sourceFileName == null)
|
|
{
|
|
sourceFileName = arg;
|
|
}
|
|
|
|
else if (sourceAudioFileName == null)
|
|
{
|
|
sourceAudioFileName = arg;
|
|
}
|
|
|
|
else if (destinationFileName == null)
|
|
{
|
|
destinationFileName = arg;
|
|
}
|
|
}
|
|
|
|
CriTable acbFile = new CriTable();
|
|
acbFile.Load(sourceFileName);
|
|
|
|
CriTable waveformTable = new CriTable();
|
|
waveformTable.Load(acbFile.Rows[0].GetValue<byte[]>("WaveformTable"));
|
|
|
|
var waveforms = waveformTable.Rows.Where(x => x.GetValue<byte>("Streaming") == 0).ToList();
|
|
var streamedWaveforms = waveformTable.Rows.Except(waveforms).ToList();
|
|
|
|
if (streamedWaveforms.Count < 1)
|
|
{
|
|
throw new InvalidDataException("This ACB file has no streamed waveforms, aka an AWB file.");
|
|
}
|
|
|
|
if (waveformId < 0)
|
|
{
|
|
while (true)
|
|
{
|
|
using (TxtBxDialog textBoxDialog = new TxtBxDialog(
|
|
streamedWaveforms.Select(x => x.GetValue<ushort>("Id")).OrderBy(x => x).Select(x => x.ToString()).ToArray()))
|
|
{
|
|
if (textBoxDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
if (!int.TryParse(textBoxDialog.Result, out waveformId) || !streamedWaveforms.Any(x => x.GetValue<ushort>("Id") == waveformId))
|
|
{
|
|
MessageBox.Show("Invalid waveform id.", "ACB Injector", MessageBoxButtons.OK);
|
|
}
|
|
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CriRow waveformToInject = streamedWaveforms.FirstOrDefault(
|
|
x => x.GetValue<ushort>("Id") == waveformId);
|
|
|
|
int newWaveformId = (waveforms.Count > 0 ?
|
|
waveforms.Max(x => x.GetValue<ushort>("Id")) : -1) + 1;
|
|
|
|
waveformToInject["Id"] = (ushort)newWaveformId;
|
|
waveformToInject["Streaming"] = (byte)0;
|
|
|
|
if (string.IsNullOrEmpty(sourceAudioFileName))
|
|
{
|
|
using (OpenFileDialog openFileDialog = new OpenFileDialog
|
|
{
|
|
Title = "Select the audio file that you are going to inject",
|
|
InitialDirectory = Path.GetDirectoryName(sourceFileName),
|
|
Filter = "All Files|*.*",
|
|
})
|
|
{
|
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
sourceAudioFileName = openFileDialog.FileName;
|
|
}
|
|
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
CriAfs2Archive archive = new CriAfs2Archive();
|
|
|
|
if (acbFile.Rows[0]["AwbFile"] is byte[] archiveData && archiveData.Length > 0)
|
|
{
|
|
archive.Load(archiveData);
|
|
|
|
// Proof that SonicAudioLib needs a rewrite.
|
|
// I hate this...
|
|
foreach (var entry in archive)
|
|
{
|
|
var filePath = new FileInfo(
|
|
Path.GetTempFileName());
|
|
|
|
File.WriteAllBytes(filePath.FullName,
|
|
archiveData.Skip((int)entry.Position).Take((int)entry.Length).ToArray());
|
|
|
|
entry.FilePath = filePath;
|
|
Junk.Add(entry.FilePath);
|
|
}
|
|
}
|
|
|
|
archive.Add(new CriAfs2Entry
|
|
{
|
|
Id = (uint)newWaveformId,
|
|
FilePath = new FileInfo(sourceAudioFileName)
|
|
});
|
|
|
|
acbFile.Rows[0]["AwbFile"] = archive.Save();
|
|
|
|
acbFile.WriterSettings =
|
|
waveformTable.WriterSettings =
|
|
CriTableWriterSettings.Adx2Settings;
|
|
|
|
acbFile.Rows[0]["WaveformTable"] = waveformTable.Save();
|
|
|
|
if (string.IsNullOrEmpty(destinationFileName))
|
|
{
|
|
if (args.Length < 2)
|
|
{
|
|
using (SaveFileDialog saveFileDialog = new SaveFileDialog
|
|
{
|
|
Title = "Save ACB file",
|
|
InitialDirectory = Path.GetDirectoryName(sourceFileName),
|
|
FileName = Path.GetFileName(sourceFileName),
|
|
Filter = "ACB Files|*.acb",
|
|
})
|
|
{
|
|
if (saveFileDialog.ShowDialog() == DialogResult.OK)
|
|
{
|
|
destinationFileName = saveFileDialog.FileName;
|
|
}
|
|
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
destinationFileName = sourceFileName;
|
|
}
|
|
}
|
|
|
|
acbFile.Save(destinationFileName);
|
|
}
|
|
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ACB Injector", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
foreach (var junk in Junk)
|
|
{
|
|
junk.Delete();
|
|
}
|
|
}
|
|
}
|
|
}
|