private void GetAdditionalFileOutputsBasedOnFormat(string filePath, AAudioBinaryFile file, byte[] fileBytes, List <AudioRebuilderFileOutput> fileOutputs) { if (Path.GetExtension(filePath).ToLower() == ".uexp") { ModifyUAsset(fileBytes, fileOutputs, file); } }
private void WriteOutAudioFiles(AAudioBinaryFile audioBinaryFile, byte[] fileBytes, string outputFolder) { var materialEntries = audioBinaryFile.MaterialSection.Entries; foreach (var entry in materialEntries) { WriteOutAudioFile(fileBytes, outputFolder, entry); } }
private void CollectMaterialToFileNames(AAudioBinaryFile audioBinaryFile, string actualFileName) { var materialEntries = audioBinaryFile.MaterialSection.Entries; foreach (var entry in materialEntries) { var extractedFileName = $"{actualFileName}_{entry.EntryIndex:D3}.hca"; _materialIndexToFileName[entry.EntryIndex] = extractedFileName; } }
private void CollectMaterialToUserNames(AAudioBinaryFile audioBinaryFile) { var materialEntries = audioBinaryFile.MaterialSection.Entries; var users = audioBinaryFile.MaterialSection.Users; foreach (var entry in materialEntries) { var entryUsers = users .Where(user => user.MaterialIndex == entry.EntryIndex) .Select(user => user.User.DisplayName); var userNames = string.Join(", ", entryUsers); _materialIndexToUserNames.Add(entry.EntryIndex, userNames); } }
private void WriteProjectFile(AAudioBinaryFile file, string outputFolder) { var config = new JsonSerializerSettings(); config.NullValueHandling = NullValueHandling.Ignore; var projectSettings = new AudioRebuilderProjectSettings() { UseWavFilesIfAvailable = true, AdditionalOutputFolders = new string[0], }; if (file is MusicAudioBinaryFile mabf) { config.NullValueHandling = NullValueHandling.Include; List <MusicTrackFixObject> originals = new List <MusicTrackFixObject>(); foreach (var entry in mabf.Entries) { foreach (var slice in entry.Slices) { var fixObject = new MusicTrackFixObject() { MusicIndex = entry.Index, SliceIndex = slice.Index, MaterialsUsed = slice.Layers.Select(x => (uint)x.MaterialIndex).ToArray(), LoopStartSample = slice.LoopStart, LoopEndSample = slice.LoopEnd, EntrySample = slice.EntryPointsSample, ExitSample = slice.ExitPointsSample }; originals.Add(fixObject); } } projectSettings.Overrides = new MusicTrackFixObject[0]; projectSettings.Originals = originals.ToArray(); } var projectFilePath = Path.Combine(outputFolder, AudioRebuilderService.RebuildSettingsFileName); string projectSettingsText = JsonConvert.SerializeObject(projectSettings, Formatting.Indented, config); File.WriteAllText(projectFilePath, projectSettingsText); Logger.Log($"Created project settings at: {projectFilePath}"); }
private void FixTotalFileSize(AAudioBinaryFile file, byte[] fileBytes) { var positionBeforeMagic = file.InnerFileStartOffset; var expectedSize = fileBytes.Length - positionBeforeMagic - file.BytesAfterFile.Length; WriteUint(fileBytes, (int)positionBeforeMagic + 0x0c, (uint)expectedSize); if (positionBeforeMagic >= 16) { WriteUint(fileBytes, (int)positionBeforeMagic - 16, (uint)expectedSize); WriteUint(fileBytes, (int)positionBeforeMagic - 12, (uint)expectedSize); } if (positionBeforeMagic >= 44) { WriteUint(fileBytes, (int)positionBeforeMagic - 44, (uint)expectedSize); } }
private void TryFixingMusicSlices(AudioRebuilderProjectSettings settings, AAudioBinaryFile file, byte[] fileBytes) { if (!(file is MusicAudioBinaryFile mab)) { return; } foreach (var fix in settings.Overrides ?? new MusicTrackFixObject[0]) { var music = mab.Entries[fix.MusicIndex]; var slice = music.Slices[fix.SliceIndex]; var fixInfo = new MusicSliceFixer() { FileBytes = fileBytes, LoopStartSample = fix.LoopStartSample, LoopEndSample = fix.LoopEndSample, EntrySample = fix.EntrySample, ExitSample = fix.ExitSample }; slice.RunFixes(fixInfo); } }
private void ModifyUAsset(byte[] fileBytes, List <AudioRebuilderFileOutput> fileOutputs, AAudioBinaryFile file) { if (!TryGettingFileByExtension(TargetFileName, ".uasset", out var uAssetFilePath)) { Logger.Error($"Failed to find project's original uasset! Looked for {TargetFileName} at: {ParentDirectory}"); return; } var uassetBytes = File.ReadAllBytes(uAssetFilePath); uint originalExpectedSize = (uint)file.Header.FileSize + (uint)file.BytesBeforeFile.Length; var originalSizeBytes = BitConverter.GetBytes(originalExpectedSize); var replacementPosition = uassetBytes.FindSubArrayInReverse(originalSizeBytes); if (replacementPosition == -1) { Logger.Error($"Failed to find UAsset file size position! Looked for value {originalExpectedSize} at {uAssetFilePath}"); return; } var offsetOverride = Settings.Parser.OverrideUAssetFileSizeOffsetFromEndOfFile; if (offsetOverride.HasValue) { replacementPosition = uassetBytes.Length - offsetOverride.Value; } Logger.Log($"Replacing UAsset file size expectation: {originalExpectedSize} -> {fileBytes.Length - 4}, at offset: {replacementPosition} (pos: {uassetBytes.Length - replacementPosition} from end-of-file)"); var replacementSizeBytes = BitConverter.GetBytes((uint)(fileBytes.Length - 4)); Buffer.BlockCopy( replacementSizeBytes, 0, uassetBytes, (int)replacementPosition, replacementSizeBytes.Length); var uassetFileOutput = new AudioRebuilderFileOutput() { Extension = ".uasset", FileBytes = uassetBytes, }; fileOutputs.Add(uassetFileOutput); }