public void TestLoadFromFile() { foreach (var unpackedDir in TestSettings.Instance.UnpackedDirs) { var platform = unpackedDir.GetPlatform(); if (platform.version == GameVersion.RS2012) { // NOTE: when unit test is finished, double click the test result to see this message Debug.WriteLine("---------------------------------"); Debug.WriteLine("TestLoadFromFile skipped RS1 file: " + unpackedDir); Debug.WriteLine("---------------------------------"); continue; } var sngPaths = Directory.EnumerateFiles(unpackedDir, "*.sng", SearchOption.AllDirectories).ToList(); foreach (var sngPath in sngPaths) { var song = Sng2014File.LoadFromFile(sngPath, platform); if (song == null) { Assert.Fail("LoadFromFile Failed: " + Path.GetFileName(unpackedDir)); } if (!song.Arrangements.Arrangements.Any()) { Assert.Fail("LoadFromFile Arrangements Failed: " + Path.GetFileName(unpackedDir)); } } } }
private static void UpdateSng2014(string songDirectory, Platform targetPlatform) { var xmlFiles = Directory.EnumerateFiles(Path.Combine(songDirectory, "songs", "arr"), "*_*.xml", SearchOption.AllDirectories).ToList(); var sngFolder = Path.Combine(songDirectory, "songs", "bin", targetPlatform.GetPathName()[1]); //-3 or more times re-calculation foreach (var xmlFile in xmlFiles) { if (File.Exists(xmlFile)) { var xmlName = Path.GetFileNameWithoutExtension(xmlFile); bool noShowlights = true; //Update Showlights if (xmlName.ToLower().Contains("_showlights")) { updateShl(xmlFile); } else { var sngFile = Path.Combine(sngFolder, xmlName + ".sng"); var arrType = ArrangementType.Guitar; if (Path.GetFileName(xmlFile).ToLower().Contains("vocal")) { arrType = ArrangementType.Vocal; } // Handle custom fonts string fontSng = null; if (arrType == ArrangementType.Vocal) { var vocSng = Sng2014File.LoadFromFile(sngFile, TryGetPlatformByEndName(songDirectory)); if (vocSng.IsCustomFont()) { vocSng.WriteChartData((fontSng = Path.GetTempFileName()), new Platform(GamePlatform.Pc, GameVersion.None)); } } using (var fs = new FileStream(sngFile, FileMode.Create)) { var sng = Sng2014File.ConvertXML(xmlFile, arrType, fontSng); sng.WriteSng(fs, targetPlatform); } noShowlights &= !xmlFiles.Any(x => Path.GetFileName(x).Contains(xmlName.Split('_')[0].ToLower() + "_showlights")); //Create Showlights if (noShowlights && arrType != ArrangementType.Vocal) { var shlName = Path.Combine(Path.GetDirectoryName(xmlFile), xmlName.Split('_')[0] + "_showlights.xml"); var shl = new RocksmithToolkitLib.DLCPackage.Showlight.Showlights(); if (shl.PopShList(shl.FixShowlights(shl.Genegate(xmlFile).ShowlightList))) { shl.Count = shl.ShowlightList.Count; using (var fs = new FileStream(shlName, FileMode.Create)) shl.Serialize(fs); } } } } } }
private void convertSngXmlButton_Click(object sender, EventArgs e) { if (String.IsNullOrEmpty(ConverterSngXmlFile)) { MessageBox.Show(String.Format("File not found: {0}: ", ConverterSngXmlFile), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error); sngXmlTB.Focus(); return; } if (sng2xmlRadio.Checked) { if (String.IsNullOrEmpty(ConverterManifestFile)) { MessageBox.Show("No manifest file was entered. The song xml file will be generated without song informations like song title, album, artist, tone names, etc.", MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error); } Attributes2014 att = null; if (ConverterArrangementType != ArrangementType.Vocal && !String.IsNullOrEmpty(ConverterManifestFile)) { att = Manifest2014 <Attributes2014> .LoadFromFile(ConverterManifestFile).Entries.ToArray()[0].Value.ToArray()[0].Value; } var sng = Sng2014File.LoadFromFile(ConverterSngXmlFile, ConverterPlatform); var outputFile = Path.Combine(Path.GetDirectoryName(ConverterSngXmlFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(ConverterSngXmlFile))); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) { dynamic xml = null; if (ConverterArrangementType == ArrangementType.Vocal) { xml = new Vocals(sng); } else { xml = new Song2014(sng, att ?? null); } xml.Serialize(outputStream); MessageBox.Show(String.Format("XML file was generated! {0}It was saved on same location of sng file specified.", Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information); } } else if (xml2sngRadio.Checked) { var outputFile = Path.Combine(Path.GetDirectoryName(ConverterSngXmlFile), String.Format("{0}.sng", Path.GetFileNameWithoutExtension(ConverterSngXmlFile))); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) { Sng2014File sng = Sng2014File.ConvertXML(ConverterSngXmlFile, ConverterArrangementType); sng.WriteSng(outputStream, ConverterPlatform); } MessageBox.Show(String.Format("SNG file was generated! {0}It was saved on same location of xml file specified.", Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information); } }
/// <summary> /// Unpack the specified File, returns unpacked dir. /// </summary> /// <param name="sourceFileName">Source file path.</param> /// <param name="savePath">Save path.</param> /// <param name="decodeAudio">If set to <c>true</c> decode audio.</param> /// <param name="extractSongXml">If set to <c>true</c> extract song xml from sng.</param> /// <param name="overwriteSongXml">If set to <c>true</c> overwrite existing song xml with produced.</param> /// <param name="predefinedPlatform">Predefined source platform.</param> public static string Unpack(string sourceFileName, string savePath, bool decodeAudio = false, bool extractSongXml = false, bool overwriteSongXml = true, Platform predefinedPlatform = null) { Platform platform = sourceFileName.GetPlatform(); if (predefinedPlatform != null && predefinedPlatform.platform != GamePlatform.None && predefinedPlatform.version != GameVersion.None) { platform = predefinedPlatform; } var fnameWithoutExt = Path.GetFileNameWithoutExtension(sourceFileName); var unpackedDir = Path.Combine(savePath, String.Format("{0}_{1}", fnameWithoutExt, platform.platform)); if (Directory.Exists(unpackedDir)) { DirectoryExtension.SafeDelete(unpackedDir); } var useCryptography = platform.version == GameVersion.RS2012; // Cryptography way is used only for PC in Rocksmith 1 switch (platform.platform) { case GamePlatform.Pc: case GamePlatform.Mac: if (platform.version == GameVersion.RS2014) { using (var inputStream = File.OpenRead(sourceFileName)) ExtractPSARC(sourceFileName, savePath, inputStream, platform); } else { using (var inputFileStream = File.OpenRead(sourceFileName)) using (var inputStream = new MemoryStream()) { if (useCryptography) { RijndaelEncryptor.DecryptFile(inputFileStream, inputStream, RijndaelEncryptor.DLCKey); } else { inputFileStream.CopyTo(inputStream); } ExtractPSARC(sourceFileName, savePath, inputStream, platform); } } break; case GamePlatform.XBox360: UnpackXBox360Package(sourceFileName, savePath, platform); break; case GamePlatform.PS3: UnpackPS3Package(sourceFileName, savePath, platform); break; case GamePlatform.None: throw new InvalidOperationException("Platform not found :("); } if (platform.platform == GamePlatform.PS3) { fnameWithoutExt = fnameWithoutExt.Substring(0, fnameWithoutExt.LastIndexOf(".")); } // DECODE AUDIO if (decodeAudio) { var audioFiles = Directory.EnumerateFiles(unpackedDir, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".ogg") || s.EndsWith(".wem")); foreach (var file in audioFiles) { var outputAudioFileName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), ".ogg")); OggFile.Revorb(file, outputAudioFileName, Path.GetDirectoryName(Application.ExecutablePath), Path.GetExtension(file).GetWwiseVersion()); } } // EXTRACT XML FROM SNG if (extractSongXml && platform.version == GameVersion.RS2014) { var sngFiles = Directory.EnumerateFiles(unpackedDir, "*.sng", SearchOption.AllDirectories); foreach (var sngFile in sngFiles) { var xmlOutput = Path.Combine(Path.GetDirectoryName(sngFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(sngFile))); xmlOutput = xmlOutput.Replace(String.Format("bin{0}{1}", Path.DirectorySeparatorChar, platform.GetPathName()[1].ToLower()), "arr"); if (File.Exists(xmlOutput) && !overwriteSongXml) { continue; } var arrType = ArrangementType.Guitar; if (Path.GetFileName(xmlOutput).ToLower().Contains("vocal")) { arrType = ArrangementType.Vocal; } Attributes2014 att = null; if (arrType != ArrangementType.Vocal) { var jsonFiles = Directory.EnumerateFiles(unpackedDir, String.Format("{0}.json", Path.GetFileNameWithoutExtension(sngFile)), SearchOption.AllDirectories).FirstOrDefault(); if (jsonFiles.Any() && !String.IsNullOrEmpty(jsonFiles)) { att = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles).Entries.ToArray()[0].Value.ToArray()[0].Value; } } var sngContent = Sng2014File.LoadFromFile(sngFile, platform); using (var outputStream = new FileStream(xmlOutput, FileMode.Create, FileAccess.ReadWrite)) { dynamic xmlContent = null; if (arrType == ArrangementType.Vocal) { xmlContent = new Vocals(sngContent); } else { xmlContent = new Song2014(sngContent, att); } xmlContent.Serialize(outputStream); } } } return(unpackedDir); }
static int Main(string[] args) { var arguments = DefaultArguments(); var options = GetOptions(arguments); try { options.Parse(args); if (arguments.ShowHelp) { options.WriteOptionDescriptions(Console.Out); return(0); } if (!arguments.Pack && !arguments.Unpack && !arguments.Sng2Xml && !arguments.Xml2Sng) { ShowHelpfulError("Must especify a primary command as 'pack', 'unpack', 'sng2xml' or 'xml2sng'."); return(1); } if (arguments.Input == null && arguments.Input.Length <= 0) { ShowHelpfulError("Must specify at least one input file."); return(1); } if (arguments.Sng2Xml && arguments.Manifest == null && arguments.Manifest.Length <= 0) { Console.WriteLine("No manifest file was entered. The song xml file will be generated without song informations like song title, album, artist, tone names, etc."); } var srcFiles = new List <string>(); foreach (var name in arguments.Input) { if (name.IsDirectory()) { srcFiles.AddRange(Directory.EnumerateFiles(Path.GetFullPath(name), "*.sng", SearchOption.AllDirectories)); } if (File.Exists(name)) { srcFiles.Add(name); } } var errorCount = 0; var indexCount = 0; foreach (string inputFile in srcFiles) { if (!File.Exists(inputFile)) { Console.WriteLine(String.Format("File '{0}' doesn't exists.", inputFile)); continue; } if (arguments.Unpack || arguments.Sng2Xml) { if (Path.GetExtension(inputFile) != ".sng") { Console.WriteLine(String.Format("File '{0}' is not support. \nOnly *.sng are supported on this command.", inputFile)); continue; } } if (arguments.Pack || arguments.Unpack) { var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}_{1}.sng", Path.GetFileNameWithoutExtension(inputFile), (arguments.Unpack) ? "decrypted" : "encrypted")); using (FileStream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read)) using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) { if (arguments.Pack) { Sng2014File.PackSng(inputStream, outputStream, new Platform(arguments.Platform, GameVersion.RS2014)); } else if (arguments.Unpack) { Sng2014File.UnpackSng(inputStream, outputStream, new Platform(arguments.Platform, GameVersion.RS2014)); } } } else if (arguments.Sng2Xml) { Attributes2014 att = null; if (arguments.ArrangementType != ArrangementType.Vocal && arguments.Manifest != null && arguments.Manifest.Length > indexCount) { att = Manifest2014 <Attributes2014> .LoadFromFile(arguments.Manifest[indexCount]).Entries.ToArray()[0].Value.ToArray()[0].Value; } var sng = Sng2014File.LoadFromFile(inputFile, new Platform(arguments.Platform, GameVersion.RS2014)); var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(inputFile))); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) { dynamic xml = null; if (arguments.ArrangementType == ArrangementType.Vocal) { xml = new Vocals(sng); } else { xml = new Song2014(sng, att ?? null); } xml.Serialize(outputStream); } } else if (arguments.Xml2Sng) { var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}.sng", Path.GetFileNameWithoutExtension(inputFile))); using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) { Sng2014File sng = Sng2014File.ConvertXML(inputFile, arguments.ArrangementType); sng.WriteSng(outputStream, new Platform(arguments.Platform, GameVersion.RS2014)); } } } if (errorCount == 0) { Console.WriteLine("Process successfully completed!"); } else if (errorCount > 0 && errorCount < srcFiles.Count) { Console.WriteLine("Process completed with errors!"); } else { Console.WriteLine("An error occurred!"); } } catch (OptionException ex) { ShowHelpfulError(ex.Message); return(1); } return(0); }
/// <summary> /// Unpack the specified File, returns unpacked dir. /// </summary> /// <param name="sourceFileName">Source file path.</param> /// <param name="savePath">Save path.</param> /// <param name="decodeAudio">If set to <c>true</c> decode audio.</param> /// <param name="overwriteSongXml">If set to <c>true</c> overwrite existing song (EOF) xml with SNG data</param> /// <param name="predefinedPlatform">Predefined source platform.</param> public static string Unpack(string sourceFileName, string savePath, bool decodeAudio = false, bool overwriteSongXml = false, Platform predefinedPlatform = null) { Platform platform = sourceFileName.GetPlatform(); if (predefinedPlatform != null && predefinedPlatform.platform != GamePlatform.None && predefinedPlatform.version != GameVersion.None) { platform = predefinedPlatform; } var fnameWithoutExt = Path.GetFileNameWithoutExtension(sourceFileName); if (platform.platform == GamePlatform.PS3) { fnameWithoutExt = fnameWithoutExt.Substring(0, fnameWithoutExt.LastIndexOf(".")); } var unpackedDir = Path.Combine(savePath, String.Format("{0}_{1}", fnameWithoutExt, platform.platform)); if (Directory.Exists(unpackedDir)) { DirectoryExtension.SafeDelete(unpackedDir); } var useCryptography = platform.version == GameVersion.RS2012; // Cryptography way is used only for PC in Rocksmith 1 switch (platform.platform) { case GamePlatform.Pc: case GamePlatform.Mac: if (platform.version == GameVersion.RS2014) { using (var inputStream = File.OpenRead(sourceFileName)) ExtractPSARC(sourceFileName, savePath, inputStream, platform); } else { using (var inputFileStream = File.OpenRead(sourceFileName)) using (var inputStream = new MemoryStream()) { if (useCryptography) { RijndaelEncryptor.DecryptFile(inputFileStream, inputStream, RijndaelEncryptor.DLCKey); } else { inputFileStream.CopyTo(inputStream); } ExtractPSARC(sourceFileName, savePath, inputStream, platform); } } break; case GamePlatform.XBox360: UnpackXBox360Package(sourceFileName, savePath, platform); break; case GamePlatform.PS3: UnpackPS3Package(sourceFileName, savePath, platform); break; case GamePlatform.None: throw new InvalidOperationException("Platform not found :("); } // DECODE AUDIO if (decodeAudio) { GlobalExtension.ShowProgress("Decoding Audio ...", 50); var audioFiles = Directory.EnumerateFiles(unpackedDir, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".ogg") || s.EndsWith(".wem")); foreach (var file in audioFiles) { var outputAudioFileName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), ".ogg")); OggFile.Revorb(file, outputAudioFileName, Path.GetDirectoryName(Application.ExecutablePath), Path.GetExtension(file).GetWwiseVersion()); } //GlobalExtension.HideProgress(); } // for debugging //overwriteSongXml = false; // Extract XML from SNG and check it against the EOF XML (correct bass tuning from older toolkit/EOF xml files) if (platform.version == GameVersion.RS2014) { var sngFiles = Directory.EnumerateFiles(unpackedDir, "*.sng", SearchOption.AllDirectories).ToList(); var step = Math.Round(1.0 / (sngFiles.Count + 2) * 100, 3); double progress = 0; GlobalExtension.ShowProgress("Extracting XML from SNG ..."); foreach (var sngFile in sngFiles) { var xmlEofFile = Path.Combine(Path.GetDirectoryName(sngFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(sngFile))); xmlEofFile = xmlEofFile.Replace(String.Format("bin{0}{1}", Path.DirectorySeparatorChar, platform.GetPathName()[1].ToLower()), "arr"); var xmlSngFile = xmlEofFile.Replace(".xml", ".sng.xml"); var arrType = ArrangementType.Guitar; if (Path.GetFileName(xmlSngFile).ToLower().Contains("vocal")) { arrType = ArrangementType.Vocal; } Attributes2014 att = null; if (arrType != ArrangementType.Vocal) { var jsonFiles = Directory.EnumerateFiles(unpackedDir, String.Format("{0}.json", Path.GetFileNameWithoutExtension(sngFile)), SearchOption.AllDirectories).FirstOrDefault(); if (!String.IsNullOrEmpty(jsonFiles) && jsonFiles.Any()) { att = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles).Entries.ToArray()[0].Value.ToArray()[0].Value; } } var sngContent = Sng2014File.LoadFromFile(sngFile, platform); using (var outputStream = new FileStream(xmlSngFile, FileMode.Create, FileAccess.ReadWrite)) { dynamic xmlContent = null; if (arrType == ArrangementType.Vocal) { xmlContent = new Vocals(sngContent); } else { xmlContent = new Song2014(sngContent, att); } xmlContent.Serialize(outputStream); } // correct old toolkit/EOF xml (tuning) issues ... sync with SNG data if (File.Exists(xmlEofFile) && !overwriteSongXml && arrType != ArrangementType.Vocal) { var eofSong = Song2014.LoadFromFile(xmlEofFile); var sngSong = Song2014.LoadFromFile(xmlSngFile); if (eofSong.Tuning != sngSong.Tuning) { eofSong.Tuning = sngSong.Tuning; var xmlComments = Song2014.ReadXmlComments(xmlEofFile); using (var stream = File.Open(xmlEofFile, FileMode.Create)) eofSong.Serialize(stream, true); Song2014.WriteXmlComments(xmlEofFile, xmlComments, customComment: "Synced with SNG file"); } File.Delete(xmlSngFile); } else { if (arrType != ArrangementType.Vocal) { Song2014.WriteXmlComments(xmlSngFile, customComment: "Generated from SNG file"); } File.Copy(xmlSngFile, xmlEofFile, true); File.Delete(xmlSngFile); } progress += step; GlobalExtension.UpdateProgress.Value = (int)progress; } //GlobalExtension.HideProgress(); } return(unpackedDir); }