Added AcbFinder update + source (#10)

* Add source for updated AcbFinder

* Added ACB Finder

* Thanks git
This commit is contained in:
Aida Enna 2020-02-28 06:38:37 -05:00 committed by GitHub
parent b27c700b5c
commit 4446fe882c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 261 additions and 2 deletions

View File

@ -22,6 +22,10 @@ This is the main library of the solution. Contains classes for IO and file form
This tool allows you to edit the audio content of an ACB file. This tool allows you to edit the audio content of an ACB file.
A more advanced version like CSB Builder is planned to be made soon. A more advanced version like CSB Builder is planned to be made soon.
## [ACB Finder](https://github.com/blueskythlikesclouds/SonicAudioTools/tree/master/Source/AcbFinder)
This tool allows you to find AWB files and link them back to the ACB, required in extracting certain ACB files.
Useful for games where the AWB files may be renamed or hidden (like Phantasy Star Online 2)
## [ACB Injector](https://github.com/blueskythlikesclouds/SonicAudioTools/tree/master/Source/AcbInjector) ## [ACB Injector](https://github.com/blueskythlikesclouds/SonicAudioTools/tree/master/Source/AcbInjector)
This tool allows you to inject audio file directly into ACB without repacking its AWB. This tool allows you to inject audio file directly into ACB without repacking its AWB.
Useful for background music ACBs that use huge AWB files. Useful for background music ACBs that use huge AWB files.

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio Version 16
VisualStudioVersion = 15.0.26430.16 VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SonicAudioLib", "Source\SonicAudioLib\SonicAudioLib.csproj", "{63138773-1F47-474C-9345-15EB6183ECC6}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SonicAudioLib", "Source\SonicAudioLib\SonicAudioLib.csproj", "{63138773-1F47-474C-9345-15EB6183ECC6}"
EndProject EndProject
@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsbBuilder", "Source\CsbBui
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcbInjector", "Source\AcbInjector\AcbInjector.csproj", "{4F68FD56-37A6-40D5-8C57-19067F7C2141}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcbInjector", "Source\AcbInjector\AcbInjector.csproj", "{4F68FD56-37A6-40D5-8C57-19067F7C2141}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AcbFinder", "Source\AcbFinder\AcbFinder.csproj", "{2F442A2E-B999-4492-B487-FA941A0E44F1}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -44,8 +46,15 @@ Global
{4F68FD56-37A6-40D5-8C57-19067F7C2141}.Debug|Any CPU.Build.0 = Debug|Any CPU {4F68FD56-37A6-40D5-8C57-19067F7C2141}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F68FD56-37A6-40D5-8C57-19067F7C2141}.Release|Any CPU.ActiveCfg = Release|Any CPU {4F68FD56-37A6-40D5-8C57-19067F7C2141}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F68FD56-37A6-40D5-8C57-19067F7C2141}.Release|Any CPU.Build.0 = Release|Any CPU {4F68FD56-37A6-40D5-8C57-19067F7C2141}.Release|Any CPU.Build.0 = Release|Any CPU
{2F442A2E-B999-4492-B487-FA941A0E44F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F442A2E-B999-4492-B487-FA941A0E44F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F442A2E-B999-4492-B487-FA941A0E44F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F442A2E-B999-4492-B487-FA941A0E44F1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0E6DA77F-A8E6-4FB2-88F6-EBCA8F977464}
EndGlobalSection
EndGlobal EndGlobal

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2F442A2E-B999-4492-B487-FA941A0E44F1}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ACBFinder</RootNamespace>
<AssemblyName>ACBFinder</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SonicAudioLib\SonicAudioLib.csproj">
<Project>{63138773-1f47-474c-9345-15eb6183ecc6}</Project>
<Name>SonicAudioLib</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>

145
Source/AcbFinder/Program.cs Normal file
View File

@ -0,0 +1,145 @@
using SonicAudioLib.CriMw;
using SonicAudioLib.IO;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace AcbFinder
{
internal static class Program
{
public static void Main(string[] args)
{
var awbsByHeaderHash = new Dictionary<string, string>();
var acbsByAwbHeaderHash = new Dictionary<string, string>();
var lines = new List<string>();
string DirectoryForWork = "";
string outputDirectory = "";
if (args.Count() < 1)
{
DirectoryForWork = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
outputDirectory = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "output");
}
else
{
DirectoryForWork = args[0];
outputDirectory = Path.Combine(args[0], "output");
}
StreamWriter LogFile = new StreamWriter(Path.Combine(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "ACB_FinderLog.txt")));
Directory.CreateDirectory(outputDirectory);
var md5 = MD5.Create();
var buffer = new byte[4];
var di = Directory.GetFiles(DirectoryForWork, "*", SearchOption.AllDirectories);
Console.WriteLine("=== ACB Finder (" + DateTime.Now + ") ===");
LogFile.WriteLine("=== ACB Finder (" + DateTime.Now + ") ===");
Console.WriteLine("Found " + di.Length + " files in " + DirectoryForWork + "...");
LogFile.WriteLine("Found " + di.Length + " files in " + DirectoryForWork + "...");
int AWBsFound = 0;
foreach (var filePath in di)
{
using (var stream = File.OpenRead(filePath))
{
stream.Read(buffer, 0, 4);
var signature = Encoding.ASCII.GetString(buffer);
if (signature == "AFS2")
{
Console.WriteLine("Found an AWB file: " + filePath.Replace(DirectoryForWork, "").Replace("\\", ""));
LogFile.WriteLine("Found an AWB file: " + filePath.Replace(DirectoryForWork, "").Replace("\\", ""));
AWBsFound++;
stream.Read(buffer, 0, 4);
int entryCount = DataStream.ReadInt32(stream);
stream.Seek(4 + (entryCount * buffer[2]), SeekOrigin.Current);
int length = (buffer[1] == 2 ? DataStream.ReadInt16(stream) : DataStream.ReadInt32(stream)) + 2;
stream.Seek(0, SeekOrigin.Begin);
var header = new byte[length];
stream.Read(header, 0, length);
string hash = Convert.ToBase64String(md5.ComputeHash(header));
awbsByHeaderHash[hash] = filePath;
}
else if (signature == "@UTF")
{
stream.Seek(0, SeekOrigin.Begin);
try
{
using (var reader = CriTableReader.Create(stream))
{
reader.Read();
string name = (((FileStream)reader.SourceStream).Name).Replace(DirectoryForWork, "").Replace("\\",""); //Properly get the filename using the stream and remove the directory from it
name = name.Remove(name.Length - 4, 4); //Remove the extension too, just in case?
File.Copy(filePath, Path.Combine(outputDirectory, name + ".acb"), true);
Console.WriteLine("Found and copied ACB: {0}", name);
LogFile.WriteLine("Found and copied ACB: {0}", name);
lines.Add($"{Path.GetFileName(filePath)}={name}.acb");
if (reader.GetLength("StreamAwbAfs2Header") != 0)
{
//using ( var reader2 = reader.GetTableReader( "StreamAwbAfs2Header" ) )
//{
// reader2.Read();
var header = reader.GetData("StreamAwbAfs2Header");
var hash = Convert.ToBase64String(md5.ComputeHash(header));
acbsByAwbHeaderHash[hash] = name;
//}
}
}
}
catch
{
Console.WriteLine("File could not be read correctly as an ACB: " + filePath.Replace(DirectoryForWork, "").Replace("\\", ""));
LogFile.WriteLine("File could not be read correctly as an ACB: " + filePath.Replace(DirectoryForWork, "").Replace("\\", ""));
continue;
}
}
}
}
foreach (var pair in awbsByHeaderHash)
{
if (!acbsByAwbHeaderHash.TryGetValue(pair.Key, out string name))
{
Console.WriteLine("AWB (" + pair.Key + ") with no ACB found.");
LogFile.WriteLine("AWB (" + pair.Key + ") with no ACB found.");
continue;
}
lines.Add($"{Path.GetFileName(pair.Value)}={name}.awb");
File.Copy(pair.Value, Path.Combine(outputDirectory, name + ".awb"), true);
Console.WriteLine("Copied awb {0}", name);
LogFile.WriteLine("Copied awb {0}", name);
}
foreach (var pair in acbsByAwbHeaderHash.Where(x => !awbsByHeaderHash.ContainsKey(x.Key)))
{
File.AppendAllText(Path.Combine(outputDirectory, "missing_awb.txt"), string.Format("{0}\n", pair.Value));
}
File.WriteAllLines(Path.Combine(outputDirectory, "file_list.txt"), lines);
Console.WriteLine("Process completed - Found " + AWBsFound + " AWB file(s). Press any key to exit.");
LogFile.WriteLine("== Process completed (" + DateTime.Now + ") - Found " + AWBsFound + " AWB file(s). Press any key to exit. ===");
LogFile.Close();
Console.ReadKey();
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ACBFinder")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ACBFinder")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2f442a2e-b999-4492-b487-fa941a0e44f1")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]