protected void InitializeCueNameToWaveformMap(FileStream fs, bool includeCueIdInFileName) { ushort cueIndex; string cueName; CriUtfTable cueNameTableUtf = new CriUtfTable(); cueNameTableUtf.Initialize(fs, (long)this.CueNameTableOffset); for (int i = 0; i < cueNameTableUtf.NumberOfRows; i++) { cueIndex = (ushort)CriUtfTable.GetUtfFieldForRow(cueNameTableUtf, i, "CueIndex"); // skip cues with unidentified waveforms (see 'vc05_0140.acb, vc10_0372.acb' in Kidou_Senshi_Gundam_AGE_Universe_Accel (PSP)) if (this.CueList[cueIndex].IsWaveformIdentified) { cueName = (string)CriUtfTable.GetUtfFieldForRow(cueNameTableUtf, i, "CueName"); this.CueList[cueIndex].CueName = cueName; this.CueList[cueIndex].CueName += CriAcbFile.GetFileExtensionForEncodeType(this.CueList[cueIndex].EncodeType); if (includeCueIdInFileName) { this.CueList[cueIndex].CueName = String.Format("{0}_{1}", this.CueList[cueIndex].CueId.ToString("D5"), this.CueList[cueIndex].CueName); } this.CueNamesToWaveforms.Add(this.CueList[cueIndex].CueName, this.CueList[cueIndex].WaveformId); } } }
// @TODO: Need to update this for Internal/External CPK protected void ExtractAwbWithCueNames(string destinationFolder, AwbToExtract whichAwb) { CriUtfTable waveformTableUtf; byte encodeType; string rawFileName; CriAfs2Archive awb; string rawFileFormat = "{0}_{1}{2}"; if (whichAwb == AwbToExtract.Internal) { awb = this.InternalAwb; } else { awb = this.ExternalAwb; } using (FileStream fs = File.Open(awb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { // use files names for internal AWB foreach (string key in this.CueNamesToWaveforms.Keys) { // extract file ParseFile.ExtractChunkToFile64(fs, (ulong)awb.Files[this.CueNamesToWaveforms[key]].FileOffsetByteAligned, (ulong)awb.Files[this.CueNamesToWaveforms[key]].FileLength, Path.Combine(destinationFolder, FileUtil.CleanFileName(key)), false, false); } //------------------------------------- // extract any items without a CueName //------------------------------------- using (FileStream acbStream = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { waveformTableUtf = new CriUtfTable(); waveformTableUtf.Initialize(acbStream, (long)this.WaveformTableOffset); } // get list of unextracted files var unextractedFiles = awb.Files.Keys.Where(x => !this.CueNamesToWaveforms.ContainsValue(x)); foreach (ushort key in unextractedFiles) { encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, key, "EncodeType"); rawFileName = String.Format(rawFileFormat, Path.GetFileNameWithoutExtension(awb.SourceFile), key.ToString("D5"), CriAcbFile.GetFileExtensionForEncodeType(encodeType)); // extract file ParseFile.ExtractChunkToFile64(fs, (ulong)awb.Files[key].FileOffsetByteAligned, (ulong)awb.Files[key].FileLength, Path.Combine(destinationFolder, rawFileName), false, false); } } }
protected void ExtractAllUsingCueList(string destinationFolder) { CriUtfTable waveformTableUtf; ushort waveformIndex; byte encodeType; string rawFileName; string rawFileFormat = "{0}.{1}{2}"; FileStream internalFs = null; FileStream externalFs = null; ArrayList internalIdsExtracted = new ArrayList(); ArrayList externalIdsExtracted = new ArrayList(); string acbAwbDestinationFolder = Path.Combine(destinationFolder, ACB_AWB_EXTRACTION_FOLDER); string extAwbDestinationFolder = Path.Combine(destinationFolder, EXT_AWB_EXTRACTION_FOLDER); string acbCpkDestinationFolder = Path.Combine(destinationFolder, ACB_CPK_EXTRACTION_FOLDER); string extCpkDestinationFolder = Path.Combine(destinationFolder, EXT_CPK_EXTRACTION_FOLDER); try { // open streams if (this.InternalAwb != null) { internalFs = File.Open(this.InternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); } else if (this.InternalCpk != null) { internalFs = File.Open(this.InternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read); } if (this.ExternalAwb != null) { externalFs = File.Open(this.ExternalAwb.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); } else if (this.ExternalCpk != null) { externalFs = File.Open(this.ExternalCpk.SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read); } // loop through cues and extract for (int i = 0; i < CueList.Length; i++) { CriAcbCueRecord cue = CueList[i]; if (cue.IsWaveformIdentified) { if (cue.IsStreaming) // external AWB file { if (this.ExternalAwb != null) { ParseFile.ExtractChunkToFile64(externalFs, (ulong)this.ExternalAwb.Files[cue.WaveformId].FileOffsetByteAligned, (ulong)this.ExternalAwb.Files[cue.WaveformId].FileLength, Path.Combine(extAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false); } else if (this.ExternalCpk != null) { ParseFile.ExtractChunkToFile64(externalFs, (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned, (ulong)this.ExternalCpk.ItocFiles[cue.WaveformId].FileLength, Path.Combine(extCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false); } externalIdsExtracted.Add(cue.WaveformId); } else // internal AWB file (inside ACB) { if (this.InternalAwb != null) { ParseFile.ExtractChunkToFile64(internalFs, (ulong)this.InternalAwb.Files[cue.WaveformId].FileOffsetByteAligned, (ulong)this.InternalAwb.Files[cue.WaveformId].FileLength, Path.Combine(acbAwbDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false); } else if (this.InternalCpk != null) { ParseFile.ExtractChunkToFile64(internalFs, (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileOffsetByteAligned, (ulong)this.InternalCpk.ItocFiles[cue.WaveformId].FileLength, Path.Combine(acbCpkDestinationFolder, FileUtil.CleanFileName(cue.CueName)), false, false); } internalIdsExtracted.Add(cue.WaveformId); } } // if (cue.IsWaveformIdentified) } // extract leftovers using (FileStream acbStream = File.Open(this.SourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { waveformTableUtf = new CriUtfTable(); waveformTableUtf.Initialize(acbStream, (long)this.WaveformTableOffset); } if (this.ExternalAwb != null) { var unextractedExternalFiles = this.ExternalAwb.Files.Keys.Where(x => !externalIdsExtracted.Contains(x)); foreach (ushort key in unextractedExternalFiles) { waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true); encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType"); rawFileName = String.Format(rawFileFormat, Path.GetFileName(this.ExternalAwb.SourceFile), key.ToString("D5"), CriAcbFile.GetFileExtensionForEncodeType(encodeType)); // extract file ParseFile.ExtractChunkToFile64(externalFs, (ulong)this.ExternalAwb.Files[key].FileOffsetByteAligned, (ulong)this.ExternalAwb.Files[key].FileLength, Path.Combine(extAwbDestinationFolder, rawFileName), false, false); } } else if (this.ExternalCpk != null) { var unextractedExternalFiles = this.ExternalCpk.ItocFiles.Keys.Where(x => !externalIdsExtracted.Contains(x)); foreach (ushort key in unextractedExternalFiles) { waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, true); encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType"); rawFileName = String.Format(rawFileFormat, Path.GetFileName(this.ExternalCpk.SourceFileName), key.ToString("D5"), CriAcbFile.GetFileExtensionForEncodeType(encodeType)); // extract file ParseFile.ExtractChunkToFile64(externalFs, (ulong)this.ExternalCpk.ItocFiles[key].FileOffsetByteAligned, (ulong)this.ExternalCpk.ItocFiles[key].FileLength, Path.Combine(extCpkDestinationFolder, rawFileName), false, false); } } if (this.InternalAwb != null) { var unextractedInternalFiles = this.InternalAwb.Files.Keys.Where(x => !internalIdsExtracted.Contains(x)); foreach (ushort key in unextractedInternalFiles) { waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false); encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType"); rawFileName = String.Format(rawFileFormat, Path.GetFileName(this.InternalAwb.SourceFile), key.ToString("D5"), CriAcbFile.GetFileExtensionForEncodeType(encodeType)); // extract file ParseFile.ExtractChunkToFile64(internalFs, (ulong)this.InternalAwb.Files[key].FileOffsetByteAligned, (ulong)this.InternalAwb.Files[key].FileLength, Path.Combine(acbAwbDestinationFolder, rawFileName), false, false); } } else if (this.InternalCpk != null) { var unextractedInternalFiles = this.InternalCpk.ItocFiles.Keys.Where(x => !internalIdsExtracted.Contains(x)); foreach (ushort key in unextractedInternalFiles) { waveformIndex = GetWaveformRowIndexForWaveformId(waveformTableUtf, key, false); encodeType = (byte)CriUtfTable.GetUtfFieldForRow(waveformTableUtf, waveformIndex, "EncodeType"); rawFileName = String.Format(rawFileFormat, Path.GetFileName(this.InternalCpk.SourceFileName), key.ToString("D5"), CriAcbFile.GetFileExtensionForEncodeType(encodeType)); // extract file ParseFile.ExtractChunkToFile64(internalFs, (ulong)this.InternalCpk.ItocFiles[key].FileOffsetByteAligned, (ulong)this.InternalCpk.ItocFiles[key].FileLength, Path.Combine(acbCpkDestinationFolder, rawFileName), false, false); } } } catch (Exception ex) { throw ex; } finally { if (internalFs != null) { internalFs.Close(); internalFs.Dispose(); } if (externalFs != null) { externalFs.Close(); externalFs.Dispose(); } } }