protected override void DoTaskForFile(string pPath, IVgmtWorkerStruct pPsf2SettingsUpdaterStruct, DoWorkEventArgs e) { Psf2SettingsUpdaterStruct iniStruct = (Psf2SettingsUpdaterStruct)pPsf2SettingsUpdaterStruct; string workingFolder = String.Empty; ////////////////////// // copy existing tags ////////////////////// string formatString = XsfUtil.GetXsfFormatString(pPath); Dictionary <string, string> tagHash; Xsf psf2File, newPsf2File; if (!String.IsNullOrEmpty(formatString) && formatString.Equals(Xsf.FormatNamePsf2)) { try { using (FileStream fs = File.Open(pPath, FileMode.Open, FileAccess.Read)) { // initialize file psf2File = new Xsf(); psf2File.Initialize(fs, pPath); // copy tags tagHash = psf2File.GetTagHash(); } /////////////// // unpack Psf2 /////////////// workingFolder = Path.Combine(Path.GetDirectoryName(pPath), Path.GetFileNameWithoutExtension(pPath)); string unpackFolder = Path.Combine(workingFolder, "unpack_dir"); XsfUtil.UnpackPsf2(pPath, unpackFolder); /////////////////// // parse .ini file /////////////////// Psf2.Psf2IniSqIrxStruct originalIni; string[] originalIniFiles = Directory.GetFiles(unpackFolder, "*.ini"); if (originalIniFiles.Length > 0) { using (FileStream iniFs = File.Open(originalIniFiles[0], FileMode.Open, FileAccess.Read)) { originalIni = Psf2.ParseClsIniFile(iniFs); } //////////////////// // update .ini file //////////////////// iniStruct.IniSettings = UpdateClsIniFile(iniStruct.IniSettings, originalIni, iniStruct.RemoveEmptySettings); File.Delete(originalIniFiles[0]); Psf2.WriteClsIniFile(iniStruct.IniSettings, originalIniFiles[0]); /////////////// // repack Psf2 /////////////// string psf2FileName = Path.GetFileName(pPath); /////////////////// // copy mkpsf2.exe /////////////////// string mkpsf2Destination = Path.Combine(workingFolder, Path.GetFileName(MKPSF2_SOURCE_PATH)); File.Copy(MKPSF2_SOURCE_PATH, mkpsf2Destination, true); ////////////////// // run mkpsf2.exe ////////////////// string arguments = String.Format(" \"{0}\" \"{1}\"", psf2FileName, unpackFolder); Process makePsf2Process = new Process(); makePsf2Process.StartInfo = new ProcessStartInfo(mkpsf2Destination, arguments); makePsf2Process.StartInfo.UseShellExecute = false; makePsf2Process.StartInfo.CreateNoWindow = true; makePsf2Process.StartInfo.WorkingDirectory = workingFolder; bool isSuccess = makePsf2Process.Start(); makePsf2Process.WaitForExit(); makePsf2Process.Close(); makePsf2Process.Dispose(); //////////////// // replace tags //////////////// string newPsf2FilePath = Path.Combine(workingFolder, psf2FileName); using (FileStream newFs = File.Open(newPsf2FilePath, FileMode.Open, FileAccess.Read)) { // initialize new file newPsf2File = new Xsf(); newPsf2File.Initialize(newFs, newPsf2FilePath); } // update to use old tag hash newPsf2File.TagHash = tagHash; newPsf2File.UpdateTags(); ///////////////////////// // replace original file ///////////////////////// File.Copy(newPsf2FilePath, pPath, true); } } catch (Exception ex) { throw ex; } finally { // delete working folder if (Directory.Exists(workingFolder)) { Directory.Delete(workingFolder, true); } } } }
private void migrateTags(Xsf2sfTagMigratorStruct pXsf2sfTagMigratorStruct) { Dictionary <int, string> sourceFiles = new Dictionary <int, string>(); int songNumber; Xsf source2sf; Xsf destination2sf; string renameFilePath; try { // build source list foreach (string f in Directory.GetFiles(pXsf2sfTagMigratorStruct.SourceDirectory, "*.*")) { songNumber = XsfUtil.GetSongNumberForYoshiIslandMini2sf(f); if (songNumber != XsfUtil.InvalidData) { if (!sourceFiles.ContainsKey(songNumber)) { sourceFiles.Add(songNumber, f); } else { this.progress = 0; this.progressStruct.Clear(); this.progressStruct.GenericMessage = String.Format( "Warning duplicate track ID for <{0}>. Does the V1 set use 2 .2sflibs? Skipping...{1}", f, Environment.NewLine); this.ReportProgress(this.progress, this.progressStruct); } } } } catch (Exception _ex) { this.progress = 0; this.progressStruct.Clear(); this.progressStruct.ErrorMessage = String.Format("Error building source directory list: {0}{1}", _ex.Message, Environment.NewLine); this.ReportProgress(this.progress, this.progressStruct); } if (sourceFiles.Count > 0) { this.maxFiles = FileUtil.GetFileCount(new string[] { pXsf2sfTagMigratorStruct.DestinationDirectory }, false); // loop through destination foreach (string f in Directory.GetFiles(pXsf2sfTagMigratorStruct.DestinationDirectory, "*.*")) { this.progress = (++fileCount * 100) / maxFiles; try { songNumber = XsfUtil.GetSongNumberForMini2sf(f); // check for source if ((songNumber != XsfUtil.InvalidData) && (sourceFiles.ContainsKey(songNumber))) { // copy the tags XsfTagCopyStruct xtcStruct = new XsfTagCopyStruct(); xtcStruct.CopyEmptyTags = pXsf2sfTagMigratorStruct.CopyEmptyTags; xtcStruct.UpdateArtistTag = pXsf2sfTagMigratorStruct.UpdateArtistTag; xtcStruct.UpdateCommentTag = pXsf2sfTagMigratorStruct.UpdateCommentTag; xtcStruct.UpdateCopyrightTag = pXsf2sfTagMigratorStruct.UpdateCopyrightTag; xtcStruct.UpdateFadeTag = pXsf2sfTagMigratorStruct.UpdateFadeTag; xtcStruct.UpdateGameTag = pXsf2sfTagMigratorStruct.UpdateGameTag; xtcStruct.UpdateGenreTag = pXsf2sfTagMigratorStruct.UpdateGenreTag; xtcStruct.UpdateLengthTag = pXsf2sfTagMigratorStruct.UpdateLengthTag; xtcStruct.UpdateSystemTag = false; xtcStruct.UpdateTitleTag = pXsf2sfTagMigratorStruct.UpdateTitleTag; xtcStruct.UpdateVolumeTag = pXsf2sfTagMigratorStruct.UpdateVolumeTag; xtcStruct.UpdateXsfByTag = pXsf2sfTagMigratorStruct.UpdateXsfByTag; xtcStruct.UpdateYearTag = pXsf2sfTagMigratorStruct.UpdateYearTag; using (FileStream sourceFs = File.Open(sourceFiles[songNumber], FileMode.Open, FileAccess.Read)) { source2sf = new Xsf(); source2sf.Initialize(sourceFs, sourceFiles[songNumber]); } using (FileStream destinationFs = File.Open(f, FileMode.Open, FileAccess.Read)) { destination2sf = new Xsf(); destination2sf.Initialize(destinationFs, f); } XsfUtil.CopyTags(source2sf, destination2sf, xtcStruct); // rename the file if (pXsf2sfTagMigratorStruct.UpdateFileName) { renameFilePath = Path.Combine(Path.GetDirectoryName(f), Path.GetFileNameWithoutExtension(sourceFiles[songNumber]) + Path.GetExtension(f)); File.Move(f, renameFilePath); } } this.progressStruct.Clear(); this.progressStruct.FileName = f; this.ReportProgress(this.progress, this.progressStruct); } catch (Exception _ex2) { this.progressStruct.Clear(); this.progressStruct.FileName = f; this.progressStruct.ErrorMessage = String.Format("Error updating <{0}>: {1}{2}", f, _ex2.Message, Environment.NewLine); this.ReportProgress(this.progress, this.progressStruct); } } //foreach } else { this.progress = 0; this.progressStruct.Clear(); this.progressStruct.ErrorMessage = String.Format("ERROR, no 2SFs found in source directory.{0}", Environment.NewLine); this.ReportProgress(this.progress, this.progressStruct); } }
private void buildPsf2Lib(Psf2ToPsf2LibStruct pPsf2ToPsf2LibStruct, DoWorkEventArgs e) { bool isSuccess; if (!Directory.Exists(pPsf2ToPsf2LibStruct.sourcePath)) { this.progressStruct = new VGMToolbox.util.ProgressStruct(); this.progressStruct.NewNode = null; this.progressStruct.FileName = null; this.progressStruct.ErrorMessage = String.Format("ERROR: Directory <{0}> Not Found.", pPsf2ToPsf2LibStruct.sourcePath); ReportProgress(0, this.progressStruct); } else { // Get Max Files this.maxFiles = Directory.GetFiles(pPsf2ToPsf2LibStruct.sourcePath, "*.psf2").Length; pPsf2ToPsf2LibStruct.libraryName = FileUtil.CleanFileName(pPsf2ToPsf2LibStruct.libraryName) + ".psf2lib"; foreach (string f in Directory.GetFiles(pPsf2ToPsf2LibStruct.sourcePath, "*.psf2")) { // report progress int progress = (++this.fileCount * 100) / maxFiles; this.progressStruct = new VGMToolbox.util.ProgressStruct(); this.progressStruct.NewNode = null; this.progressStruct.FileName = f; ReportProgress(progress, this.progressStruct); using (FileStream fs = File.OpenRead(f)) { // check type Type dataType = FormatUtil.getObjectType(fs); if (dataType != null && dataType.Name.Equals("Xsf")) { Xsf psf2File = new Xsf(); psf2File.Initialize(fs, f); if (psf2File.GetFormat().Equals(Xsf.FormatNamePsf2)) { // copy tags Dictionary <string, string> tagHash = psf2File.GetTagHash(); // unpack files string outputDir = Path.Combine(PSF2_WORKING_FOLDER, Path.GetFileNameWithoutExtension(f)); isSuccess = this.unpackPsf2File(f, outputDir); if (isSuccess) { // move non.ini files to lib working dir isSuccess = moveNonIniFiles(outputDir, PSF2LIB_WORKING_SUBFOLDER); // make simple psf2 with just pointer .ini isSuccess = makeMiniPsf2(outputDir); if (isSuccess) { // update tag script addTagsToTagScript(f, tagHash, pPsf2ToPsf2LibStruct.libraryName); } } } // if (psf2File.getFormat().Equals(Xsf.FORMAT_NAME_PSF2)) } // if (dataType != null && dataType.Name.Equals("Xsf")) fs.Close(); } // using (FileStream fs = File.OpenRead(f)) } // foreach (string f in Directory.GetFiles(pPsf2ToPsf2LibStruct.sourcePath, "*.psf2")) // combine files into lib makePsf2Lib(PSF2LIB_WORKING_SUBFOLDER, pPsf2ToPsf2LibStruct.libraryName); // execute tagging script executeBatchScript(); // move completed psf2s to rip folder doCleanup(pPsf2ToPsf2LibStruct); } }
static void Main(string[] args) { if ((args.Length > 3) || (args.Length < 2)) { Console.WriteLine("usage: sdatopt.exe fileName start_sequence end_sequence"); Console.WriteLine(" sdatopt.exe fileName ALL"); Console.WriteLine(" sdatopt.exe fileName PREP"); Console.WriteLine(" sdatopt.exe fileName MAP smap_file"); Console.WriteLine(" sdatopt.exe fileName MAP"); Console.WriteLine(); Console.WriteLine("fileName: .sdat or .2sflib containing SDAT to optimize"); Console.WriteLine("start_sequence: starting sequence number to keep"); Console.WriteLine("end_sequence: endinging sequence number to keep"); Console.WriteLine("ALL: use this if you wish to keep all sequences"); Console.WriteLine("PREP: use this to output an SMAP to use for sequence selection. Delete the entire line of sequences you do not want to include."); Console.WriteLine("MAP smap_file: uses smap_file from PREP to select sequences to keep."); Console.WriteLine("MAP: looks for an smap file based on the sdat name select sequences to keep. Must be in proper format."); } else { Sdat sdat = null; bool is2sfSource = false;; string sdatDirectory; string sdatOptimizingFileName; string sdatOptimizingPath; string sdatCompletedFileName; string sdatCompletedPath; int startSequence = Sdat.NO_SEQUENCE_RESTRICTION; int endSequence = Sdat.NO_SEQUENCE_RESTRICTION; string[] extractedSdats = null; string decompressedDataPath = null; string extractedToFolder = null; ArrayList cleanupList = new ArrayList(); string filename = Path.GetFullPath(args[0]); string smapFileName = null; if (!File.Exists(filename)) { Console.WriteLine("Cannot find SDAT: {0}", filename); return; } if (args[1].Trim().ToUpper().Equals("MAP")) { if (args.Length < 3) { smapFileName = Path.ChangeExtension(filename, Smap.FILE_EXTENSION); } else { smapFileName = Path.GetFullPath(args[2]); } if (!File.Exists(smapFileName)) { Console.WriteLine("Cannot find SMAP: {0}", smapFileName); return; } } sdatDirectory = Path.GetDirectoryName(filename); sdatOptimizingFileName = String.Format("{0}_OPTIMIZING{1}", Path.GetFileNameWithoutExtension(filename), Path.GetExtension(filename)); sdatOptimizingPath = Path.Combine(sdatDirectory, sdatOptimizingFileName); sdatCompletedFileName = String.Format("{0}_OPTIMIZED{1}", Path.GetFileNameWithoutExtension(filename), Path.GetExtension(filename)); sdatCompletedPath = Path.Combine(sdatDirectory, sdatCompletedFileName); try { File.Copy(filename, sdatOptimizingPath, true); using (FileStream fs = File.Open(sdatOptimizingPath, FileMode.Open, FileAccess.Read)) { Type dataType = FormatUtil.getObjectType(fs); if (dataType != null) { if (dataType.Name.Equals("Sdat")) { Console.WriteLine("Input file is an SDAT."); Console.WriteLine("Building Internal SDAT."); sdat = new Sdat(); sdat.Initialize(fs, sdatOptimizingPath); } else if (dataType.Name.Equals("Xsf")) // is an Xsf, confirm it is a 2sf { Xsf libFile = new Xsf(); libFile.Initialize(fs, sdatOptimizingPath); if (libFile.GetFormat().Equals(Xsf.FormatName2sf)) { Console.WriteLine("Input file is a 2SF."); is2sfSource = true; // close stream, we're gonna need this file fs.Close(); fs.Dispose(); // unpack compressed section Console.WriteLine("Decompressing Compressed Data section of 2SF."); Xsf2ExeStruct xsf2ExeStruct = new Xsf2ExeStruct(); xsf2ExeStruct.IncludeExtension = true; xsf2ExeStruct.StripGsfHeader = false; decompressedDataPath = XsfUtil.ExtractCompressedDataSection(sdatOptimizingPath, xsf2ExeStruct); // extract SDAT Console.WriteLine("Extracting SDAT from Decompressed Compressed Data Section."); VGMToolbox.util.FindOffsetStruct findOffsetStruct = new VGMToolbox.util.FindOffsetStruct(); findOffsetStruct.SearchString = Sdat.ASCII_SIGNATURE_STRING; findOffsetStruct.TreatSearchStringAsHex = true; findOffsetStruct.CutFile = true; findOffsetStruct.SearchStringOffset = "0"; findOffsetStruct.CutSize = "8"; findOffsetStruct.CutSizeOffsetSize = "4"; findOffsetStruct.IsCutSizeAnOffset = true; findOffsetStruct.OutputFileExtension = ".sdat"; findOffsetStruct.IsLittleEndian = true; findOffsetStruct.UseTerminatorForCutSize = false; findOffsetStruct.TerminatorString = null; findOffsetStruct.TreatTerminatorStringAsHex = false; findOffsetStruct.IncludeTerminatorLength = false; findOffsetStruct.ExtraCutSizeBytes = null; string output; extractedToFolder = ParseFile.FindOffsetAndCutFile(decompressedDataPath, findOffsetStruct, out output, false, false); // create SDAT object Console.WriteLine("Building Internal SDAT."); extractedSdats = Directory.GetFiles(extractedToFolder, "*.sdat"); if (extractedSdats.Length > 1) { Console.WriteLine("Sorry, this 2SF file contains more than 1 SDAT. sdatopt cannot currently handle this."); return; } else if (extractedSdats.Length == 0) { Console.WriteLine("ERROR: Did not find an SDAT in the Decompressed Data Section."); return; } else { using (FileStream sdatFs = File.Open(extractedSdats[0], FileMode.Open, FileAccess.Read)) { sdat = new Sdat(); sdat.Initialize(sdatFs, extractedSdats[0]); } } } } else { Console.WriteLine("ERROR: Cannot determine format of the input file."); return; } } } if (sdat != null) { if (args[1].Trim().ToUpper().Equals("PREP")) { sdat.BuildSmapPrep(Path.GetDirectoryName(filename), Path.GetFileNameWithoutExtension(filename)); } else if (args[1].Trim().ToUpper().Equals("MAP")) { ArrayList allowedSequences = buildSequenceList(smapFileName); Console.WriteLine("Optimizing SDAT."); sdat.OptimizeForZlib(allowedSequences); } else { if (!args[1].Trim().ToUpper().Equals("ALL")) { if (!String.IsNullOrEmpty(args[1])) { startSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(args[1]); } if (!String.IsNullOrEmpty(args[2])) { endSequence = (int)VGMToolbox.util.ByteConversion.GetLongValueFromString(args[2]); } } Console.WriteLine("Optimizing SDAT."); sdat.OptimizeForZlib(startSequence, endSequence); } } if (is2sfSource) { if (!args[1].Trim().ToUpper().Equals("PREP")) { // replace SDAT section Console.WriteLine("Inserting SDAT back into Decompressed Compressed Data Section."); long sdatOffset; using (FileStream dcFs = File.Open(decompressedDataPath, FileMode.Open, FileAccess.ReadWrite)) { sdatOffset = ParseFile.GetNextOffset(dcFs, 0, Sdat.ASCII_SIGNATURE); } FileInfo fi = new FileInfo(extractedSdats[0]); FileUtil.ReplaceFileChunk(extractedSdats[0], 0, fi.Length, decompressedDataPath, sdatOffset); // rebuild 2sf Console.WriteLine("Rebuilding 2sf File."); string bin2PsfStdOut = String.Empty; string bin2PsfStdErr = String.Empty; XsfUtil.Bin2Psf(Path.GetExtension(filename).Substring(1), (int)Xsf.Version2sf, decompressedDataPath, ref bin2PsfStdOut, ref bin2PsfStdErr); Console.WriteLine("Cleaning up intermediate files."); File.Copy(Path.ChangeExtension(decompressedDataPath, Path.GetExtension(filename)), sdatOptimizingPath, true); File.Delete(Path.ChangeExtension(decompressedDataPath, Path.GetExtension(filename))); } File.Delete(decompressedDataPath); Directory.Delete(extractedToFolder, true); } if (!args[1].Trim().ToUpper().Equals("PREP")) { Console.WriteLine("Copying to OPTIMIZED file."); File.Copy(sdatOptimizingPath, sdatCompletedPath, true); } Console.WriteLine("Deleting OPTIMIZING file."); File.Delete(sdatOptimizingPath); Console.WriteLine("Optimization Complete."); } catch (Exception ex) { Console.WriteLine(String.Format("ERROR: {0}", ex.Message)); } } }