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); } }
private static List <Tone2014> ReadFromManifest(string manifestFilePath) { List <Tone2014> tones = new List <Tone2014>(); Attributes2014 jsonManifestAttributes = Manifest2014 <Attributes2014> .LoadFromFile(manifestFilePath).Entries.ToArray()[0].Value.ToArray()[0].Value; if (jsonManifestAttributes.ArrangementName != ArrangementName.Vocals.ToString() && jsonManifestAttributes.Tones != null) { tones.AddRange(jsonManifestAttributes.Tones); } return(tones); }
private static void UpdateManifest2014(string songDirectory, Platform platform) { // UPDATE MANIFEST (RS2014) if (platform.version == GameVersion.RS2014) { var xmlFiles = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories); var jsonFiles = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories); foreach (var xml in xmlFiles) { var xmlName = Path.GetFileNameWithoutExtension(xml); if (xmlName.ToUpperInvariant().Contains("SHOWLIGHT")) { continue; } if (xmlName.ToUpperInvariant().Contains("VOCAL")) { continue;//TODO: Re-generate vocals manifest. } string json = jsonFiles.Where(name => Path.GetFileNameWithoutExtension(name) == xmlName).FirstOrDefault(); if (!String.IsNullOrEmpty(json)) { var xmlContent = Song2014.LoadFromFile(xml); var manifest = new Manifest2014 <Attributes2014>(); var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.First().Value.First().Value; var manifestFunctions = new ManifestFunctions(platform.version); attr.PhraseIterations = new List <Manifest.PhraseIteration>(); manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version); attr.Phrases = new List <Manifest.Phrase>(); manifestFunctions.GeneratePhraseData(attr, xmlContent); attr.Sections = new List <Manifest.Section>(); manifestFunctions.GenerateSectionData(attr, xmlContent); attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent); var attributeDictionary = new Dictionary <string, Attributes2014> { { "Attributes", attr } }; manifest.Entries.Add(attr.PersistentID, attributeDictionary); manifest.SaveToFile(json); } } } }
private static void GeneratePedalsRS2014(string inputDir) { //inputDir like "......\ROCKSMITH\gears_Pc\manifests\gears" (gears_Pc is gears.psarc unpacked) var gearsJsonFiles = Directory.EnumerateFiles(inputDir, "*.json"); List <ToolkitPedal> toolkitPedals = new List <ToolkitPedal>(); foreach (var file in gearsJsonFiles) { var gearManifest = Manifest2014 <RsToneRS2014> .LoadFromFile(file); foreach (var pedal in gearManifest.Entries) { toolkitPedals.Add(pedal.Value["Attributes"].ToPedal()); } } JsonSerializerSettings jss = new JsonSerializerSettings(); jss.Formatting = Formatting.Indented; File.WriteAllText("pedals2014.json", JsonConvert.SerializeObject(toolkitPedals, jss)); }
/// <summary> /// Transforms unpacked Song into project-like folder structure. /// </summary> /// <returns>Output folder path.</returns> /// <param name="unpackedDir">Unpacked dir.</param> public static string DoLikeProject(string unpackedDir) { const string EOF = "EOF"; const string KIT = "Toolkit"; string SongName = "SongName"; string songVersion = "v0"; // Get name for a new folder var jsonFiles = Directory.EnumerateFiles(unpackedDir, "*.json", SearchOption.AllDirectories).ToArray(); var attr = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value; var fileNameParts = Path.GetFileNameWithoutExtension(unpackedDir).Split('_'); if (fileNameParts.Length > 3) { songVersion = fileNameParts[2]; } SongName = attr.FullName.Split('_')[0]; //Create dir struct var outdir = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", SongName, songVersion).Replace(" ", "-")); var eofdir = Path.Combine(outdir, EOF); var kitdir = Path.Combine(outdir, KIT); attr = null; //dispose // Don't work in same dir if (Directory.Exists(outdir)) { if (outdir == unpackedDir) { return(unpackedDir); } DirectoryExtension.SafeDelete(outdir); } Directory.CreateDirectory(outdir); Directory.CreateDirectory(eofdir); Directory.CreateDirectory(kitdir); var xmlFiles = Directory.EnumerateFiles(unpackedDir, "*.xml", SearchOption.AllDirectories).ToArray(); var sngFiles = Directory.EnumerateFiles(unpackedDir, "*vocals.sng", SearchOption.AllDirectories).ToArray(); foreach (var json in jsonFiles) { var name = Path.GetFileNameWithoutExtension(json); var xmlFile = xmlFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == name); var sngFile = sngFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == name); //Move all pair JSON\XML File.Move(json, Path.Combine(kitdir, name + ".json")); File.Move(xmlFile, Path.Combine(eofdir, name + ".xml")); if (name.EndsWith("vocals", StringComparison.Ordinal)) { File.Move(sngFile, Path.Combine(kitdir, name + ".sng")); } } // move showlights.xml var showlightPath = Directory.EnumerateFiles(unpackedDir, "*_showlights.xml", SearchOption.AllDirectories).ToArray(); if (showlightPath.Any()) { File.Move(showlightPath[0], Path.Combine(eofdir, Path.GetFileName(showlightPath[0]))); } //Move all art_size.dds to KIT folder var artFiles = Directory.EnumerateFiles(unpackedDir, "album_*_*.dds", SearchOption.AllDirectories).ToArray(); if (artFiles.Any()) { foreach (var art in artFiles) { File.Move(art, Path.Combine(kitdir, Path.GetFileName(art))); } } var lyricArt = Directory.EnumerateFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories).ToArray(); if (lyricArt.Any()) { foreach (var art in lyricArt) { File.Move(art, Path.Combine(kitdir, Path.GetFileName(art))); } } //Move ogg to EOF folder + rename var oggFiles = Directory.EnumerateFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories).ToArray(); if (!oggFiles.Any()) { throw new InvalidDataException("Audio files not found."); } // TODO: read names from bnk and rename. // TODO: FIX THIS ... not valid for short jingle/riff CDLC < 30 seconds // because the preview 30 seconds is larger than actual song // need to base preview decision on duration not size var a0 = new FileInfo(oggFiles[0]); if (oggFiles.Count() == 2) { var b0 = new FileInfo(oggFiles[1]); if (a0.Length > b0.Length) { File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg")); File.Move(b0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg")); } else { File.Move(b0.FullName, Path.Combine(eofdir, SongName + ".ogg")); File.Move(a0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg")); } } else { File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg")); } //Move wem to KIT folder + rename var wemFiles = Directory.EnumerateFiles(unpackedDir, "*.wem", SearchOption.AllDirectories).ToArray(); if (!wemFiles.Any()) { throw new InvalidDataException("Audio files not found."); } // TODO: FIX THIS ... not valid for short jingle/riff CDLC < 30 seconds // because the preview 30 seconds is larger than actual song // need to base preview decision on duration not size var a1 = new FileInfo(wemFiles[0]); if (wemFiles.Count() == 2) { var b1 = new FileInfo(wemFiles[1]); if (a1.Length > b1.Length) { File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem")); File.Move(b1.FullName, Path.Combine(kitdir, SongName + "_preview.wem")); } else { File.Move(b1.FullName, Path.Combine(kitdir, SongName + ".wem")); File.Move(a1.FullName, Path.Combine(kitdir, SongName + "_preview.wem")); } } else { File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem")); } //Move Appid for correct template generation. var appidFile = Directory.EnumerateFiles(unpackedDir, "*.appid", SearchOption.AllDirectories).FirstOrDefault(); if (appidFile != null) { File.Move(appidFile, Path.Combine(kitdir, Path.GetFileName(appidFile))); } //Move toolkit.version var toolkitVersion = Directory.EnumerateFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories).FirstOrDefault(); if (toolkitVersion != null) { File.Move(toolkitVersion, Path.Combine(kitdir, Path.GetFileName(toolkitVersion))); } //Remove old folder DirectoryExtension.SafeDelete(unpackedDir); return(outdir); }
/// <summary> /// Loads required DLC info from folder. /// </summary> /// <returns>The DLCPackageData info.</returns> /// <param name="unpackedDir">Unpacked dir.</param> /// <param name="targetPlatform">Target platform.</param> /// <param name = "sourcePlatform"></param> /// <param name="ignoreMultitoneEx">Ignore multitone exceptions</param> public static DLCPackageData LoadFromFolder(string unpackedDir, Platform targetPlatform, Platform sourcePlatform = null, bool ignoreMultitoneEx = false) { var data = new DLCPackageData(); data.GameVersion = GameVersion.RS2014; data.SignatureType = PackageMagic.CON; if (sourcePlatform == null) { sourcePlatform = unpackedDir.GetPlatform(); } //Arrangements / Tones data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); //Load files var jsonFiles = Directory.EnumerateFiles(unpackedDir, "*.json", SearchOption.AllDirectories).ToArray(); foreach (var json in jsonFiles) { var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value; var xmlName = attr.SongXml.Split(':')[3]; var xmlFile = Directory.EnumerateFiles(unpackedDir, xmlName + ".xml", SearchOption.AllDirectories).FirstOrDefault(); if (attr.Phrases != null) { if (data.SongInfo == null) { // Fill Package Data data.Name = attr.DLCKey; data.Volume = (attr.SongVolume == 0 ? -12 : attr.SongVolume); //FIXME: too low song volume issue, revert to -6 to fix. data.PreviewVolume = (attr.PreviewVolume ?? data.Volume); // Fill SongInfo data.SongInfo = new SongInfo { SongDisplayName = attr.SongName, SongDisplayNameSort = attr.SongNameSort, Album = attr.AlbumName, AlbumSort = attr.AlbumNameSort, SongYear = attr.SongYear ?? 0, Artist = attr.ArtistName, ArtistSort = attr.ArtistNameSort, AverageTempo = (int)attr.SongAverageTempo }; } // Adding Arrangement data.Arrangements.Add(new Arrangement(attr, xmlFile, ignoreMultitoneEx)); // make a list of tone names used in arrangements var toneNames = new List <string>(); foreach (var arr in data.Arrangements) { if (!String.IsNullOrEmpty(arr.ToneA)) { toneNames.Add(arr.ToneA); } if (!String.IsNullOrEmpty(arr.ToneB)) { toneNames.Add(arr.ToneB); } if (!String.IsNullOrEmpty(arr.ToneC)) { toneNames.Add(arr.ToneC); } if (!String.IsNullOrEmpty(arr.ToneD)) { toneNames.Add(arr.ToneD); } if (!String.IsNullOrEmpty(arr.ToneBase)) { toneNames.Add(arr.ToneBase); } } // Adding Tones foreach (var jsonTone in attr.Tones) { if (jsonTone == null) { continue; } var key = jsonTone.Key; if (data.TonesRS2014.All(t => t.Key != key)) { // fix tones names that do not have the correct alphacase for cross matching if (attr.Tone_Base.ToLower() == jsonTone.Name.ToLower() && attr.Tone_Base != jsonTone.Name) { jsonTone.Name = attr.Tone_Base; } if (attr.Tone_A != null && attr.Tone_A.ToLower() == jsonTone.Name.ToLower() && attr.Tone_A != jsonTone.Name) { jsonTone.Name = attr.Tone_A; } if (attr.Tone_B != null && attr.Tone_B.ToLower() == jsonTone.Name.ToLower() && attr.Tone_B != jsonTone.Name) { jsonTone.Name = attr.Tone_B; } if (attr.Tone_C != null && attr.Tone_C.ToLower() == jsonTone.Name.ToLower() && attr.Tone_C != jsonTone.Name) { jsonTone.Name = attr.Tone_C; } if (attr.Tone_D != null && attr.Tone_D.ToLower() == jsonTone.Name.ToLower() && attr.Tone_D != jsonTone.Name) { jsonTone.Name = attr.Tone_D; } // this is part of multitone exception handling auto convert to single tone arrangment // make data.TonesRS2014 consistent with data.Arragment.Tones (toneNames) if (toneNames.Contains(jsonTone.Name)) { data.TonesRS2014.Add(jsonTone); } } } } else if (xmlFile.ToLower().Contains("_vocals")) { var voc = new Arrangement { Name = attr.JapaneseVocal == true ? ArrangementName.JVocals : ArrangementName.Vocals, ArrangementType = ArrangementType.Vocal, ScrollSpeed = 20, SongXml = new SongXML { File = xmlFile }, SongFile = new SongFile { File = "" }, CustomFont = attr.JapaneseVocal == true }; // Get symbols stuff from _vocals.xml var fontSng = Path.Combine(unpackedDir, xmlName + ".sng"); var vocSng = Sng2014FileWriter.ReadVocals(xmlFile); if (vocSng.IsCustomFont()) { voc.CustomFont = true; voc.FontSng = fontSng; vocSng.WriteChartData(fontSng, new Platform(GamePlatform.Pc, GameVersion.None)); } voc.Sng2014 = Sng2014File.ConvertXML(xmlFile, ArrangementType.Vocal, voc.FontSng); // Adding Arrangement data.Arrangements.Add(voc); } } //ShowLights XML var xmlShowLights = Directory.EnumerateFiles(unpackedDir, "*_showlights.xml", SearchOption.AllDirectories).FirstOrDefault(); if (!String.IsNullOrEmpty(xmlShowLights)) { var shl = new Arrangement { ArrangementType = ArrangementType.ShowLight, Name = ArrangementName.ShowLights, SongXml = new SongXML { File = xmlShowLights }, SongFile = new SongFile { File = "" } }; // Adding ShowLights data.Arrangements.Add(shl); data.Showlights = true; } //Get DDS Files var ddsFiles = Directory.EnumerateFiles(unpackedDir, "album_*.dds", SearchOption.AllDirectories).ToArray(); if (ddsFiles.Any()) { var ddsFilesC = new List <DDSConvertedFile>(); foreach (var file in ddsFiles) { switch (Path.GetFileNameWithoutExtension(file).Split('_')[2]) { case "256": data.AlbumArtPath = file; ddsFilesC.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "128": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "64": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; } } data.ArtFiles = ddsFilesC; } // Lyric Art var lyricArt = Directory.EnumerateFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories).ToArray(); if (lyricArt.Any()) { data.LyricArtPath = lyricArt.FirstOrDefault(); } //Get other files //Audio files var targetAudioFiles = new List <string>(); var sourceAudioFiles = Directory.EnumerateFiles(unpackedDir, "*.wem", SearchOption.AllDirectories).ToArray(); foreach (var file in sourceAudioFiles) { var newFile = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), Path.GetExtension(file))); if (targetPlatform.IsConsole != (sourcePlatform = file.GetAudioPlatform()).IsConsole) { OggFile.ConvertAudioPlatform(file, newFile); targetAudioFiles.Add(newFile); } else { targetAudioFiles.Add(file); } } if (!targetAudioFiles.Any()) { throw new InvalidDataException("Audio files not found."); } string audioPath = null, audioPreviewPath = null; var a = new FileInfo(targetAudioFiles[0]); if (targetAudioFiles.Count == 2) { var b = new FileInfo(targetAudioFiles[1]); if (a.Length > b.Length) { audioPath = a.FullName; audioPreviewPath = b.FullName; } else { audioPath = b.FullName; audioPreviewPath = a.FullName; } } else { audioPath = a.FullName; } data.OggPath = audioPath; //Make Audio preview with expected name when rebuild if (!String.IsNullOrEmpty(audioPreviewPath)) { var newPreviewFileName = Path.Combine(Path.GetDirectoryName(audioPath), String.Format("{0}_preview{1}", Path.GetFileNameWithoutExtension(audioPath), Path.GetExtension(audioPath))); File.Move(audioPreviewPath, newPreviewFileName); data.OggPreviewPath = newPreviewFileName; } //AppID var appidFile = Directory.EnumerateFiles(unpackedDir, "*.appid", SearchOption.AllDirectories).FirstOrDefault(); if (appidFile != null) { data.AppId = File.ReadAllText(appidFile); } // Package Info var versionFile = Directory.EnumerateFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories).FirstOrDefault(); if (versionFile != null) { var tkInfo = GeneralExtensions.ReadToolkitInfo(versionFile); data.PackageVersion = tkInfo.PackageVersion; data.PackageComment = tkInfo.PackageComment; } else { data.PackageVersion = "1"; data.PackageComment = ""; } return(data); }
private int ApplyPackageDD(string file, string remSUS, string rampPath, out string consoleOutputPkg) { int singleResult = -1; bool exitedByError = false; consoleOutputPkg = String.Empty; var tmpDir = Path.GetTempPath(); var platform = file.GetPlatform(); var unpackedDir = Packer.Unpack(file, tmpDir, false, true, false); var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories); foreach (var xml in xmlFiles) { if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("vocal")) { continue; } if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("showlight")) { continue; } singleResult = ApplyDD(xml, remSUS, rampPath, out consoleOutputPkg, true, false); // UPDATE MANIFEST (RS2014) for update if (platform.version == RocksmithToolkitLib.GameVersion.RS2014) { var json = Directory.GetFiles(unpackedDir, String.Format("*{0}.json", Path.GetFileNameWithoutExtension(xml)), SearchOption.AllDirectories); if (json.Length > 0) { Attributes2014 attr = Manifest2014 <Attributes2014> .LoadFromFile(json[0]).Entries.ToArray()[0].Value.ToArray()[0].Value; Song2014 xmlContent = Song2014.LoadFromFile(xml); var manifestFunctions = new ManifestFunctions(platform.version); attr.PhraseIterations = new List <PhraseIteration>(); manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version); attr.Phrases = new List <Phrase>(); manifestFunctions.GeneratePhraseData(attr, xmlContent); attr.Sections = new List <Section>(); manifestFunctions.GenerateSectionData(attr, xmlContent); attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent); var manifest = new Manifest2014 <Attributes2014>(); var attributeDictionary = new Dictionary <string, Attributes2014> { { "Attributes", attr } }; manifest.Entries.Add(attr.PersistentID, attributeDictionary); manifest.SaveToFile(json[0]); } } if (singleResult == 1) { exitedByError = true; break; } else if (singleResult == 2) { consoleOutputPkg = String.Format("Arrangement file '{0}' => {1}", Path.GetFileNameWithoutExtension(xml), consoleOutputPkg); } } if (!exitedByError) { var newName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_{1}{2}", Path.GetFileNameWithoutExtension(file).StripPlatformEndName().GetValidName(false).Replace("_DD", "").Replace("_NDD", ""), isNDD ? "NDD" : "DD", platform.GetPathName()[2])); Packer.Pack(unpackedDir, newName, true, platform); DirectoryExtension.SafeDelete(unpackedDir); } return(singleResult); }
/// <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); }
public static string DoLikeProject(string unpackedDir) { //Get name for new folder name string outdir = ""; string EOF = "EOF"; string KIT = "Toolkit"; string SongName = "SongName"; var jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories); var attr = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value; //Create dir sruct SongName = attr.FullName.Split('_')[0]; outdir = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", attr.ArtistNameSort.GetValidName(false), attr.SongNameSort.GetValidName(false))); if (Directory.Exists(outdir)) { outdir += "_" + DateTime.Now.ToString("yyyy-MM-dd"); } Directory.CreateDirectory(outdir); Directory.CreateDirectory(Path.Combine(outdir, EOF)); Directory.CreateDirectory(Path.Combine(outdir, KIT)); foreach (var json in jsonFiles) { var atr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value; var Name = atr.SongXml.Split(':')[3]; var xmlFile = Directory.GetFiles(unpackedDir, Name + ".xml", SearchOption.AllDirectories)[0]; //Move all pair JSON\XML File.Move(json, Path.Combine(outdir, KIT, Name + ".json")); File.Move(xmlFile, Path.Combine(outdir, EOF, Name + ".xml")); } //Move art_256.dds to KIT folder var ArtFile = Directory.GetFiles(unpackedDir, "*_256.dds", SearchOption.AllDirectories); if (ArtFile.Length > 0) { File.Move(ArtFile[0], Path.Combine(outdir, KIT, Path.GetFileName(ArtFile[0]))); } //Move ogg to EOF folder + rename var OggFiles = Directory.GetFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories); if (OggFiles.Count() <= 0) { throw new InvalidDataException("Audio files not found."); } var a0 = new FileInfo(OggFiles[0]); FileInfo b0 = null; if (OggFiles.Count() == 2) { b0 = new FileInfo(OggFiles[1]); if (a0.Length > b0.Length) { File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg")); File.Move(b0.FullName, Path.Combine(outdir, EOF, SongName + "_preview.ogg")); } else { File.Move(b0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg")); File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + "_preview.ogg")); } } else { File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg")); } //Move wem to KIT folder + rename var WemFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories); if (WemFiles.Count() <= 0) { throw new InvalidDataException("Audio files not found."); } var a1 = new FileInfo(WemFiles[0]); FileInfo b1 = null; if (WemFiles.Count() == 2) { b1 = new FileInfo(WemFiles[1]); if (a1.Length > b1.Length) { File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + ".wem")); File.Move(b1.FullName, Path.Combine(outdir, KIT, SongName + "_preview.wem")); } else { File.Move(b1.FullName, Path.Combine(outdir, KIT, SongName + ".wem")); File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + "_preview.wem")); } } else { File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + ".wem")); } //Move Appid for correct template generation. var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories); if (appidFile.Length > 0) { File.Move(appidFile[0], Path.Combine(outdir, KIT, Path.GetFileName(appidFile[0]))); } //Remove old folder DirectoryExtension.SafeDelete(unpackedDir); return(outdir); }
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); }
public static DLCPackageData LoadFromFile(string unpackedDir, Platform targetPlatform) { //Load files var jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories); var data = new DLCPackageData(); data.GameVersion = GameVersion.RS2014; data.SignatureType = PackageMagic.CON; //Get Arrangements / Tones data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); foreach (var json in jsonFiles) { Attributes2014 attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value; var xmlName = attr.SongXml.Split(':')[3]; var xmlFile = Directory.GetFiles(unpackedDir, xmlName + ".xml", SearchOption.AllDirectories)[0]; if (attr.Phrases != null) { if (data.SongInfo == null) { // Fill Package Data data.Name = attr.DLCKey; data.Volume = attr.SongVolume; data.PreviewVolume = (attr.PreviewVolume != null) ? (float)attr.PreviewVolume : data.Volume; // Fill SongInfo data.SongInfo = new SongInfo(); data.SongInfo.SongDisplayName = attr.SongName; data.SongInfo.SongDisplayNameSort = attr.SongNameSort; data.SongInfo.Album = attr.AlbumName; data.SongInfo.SongYear = attr.SongYear ?? 0; data.SongInfo.Artist = attr.ArtistName; data.SongInfo.ArtistSort = attr.ArtistNameSort; data.SongInfo.AverageTempo = (int)attr.SongAverageTempo; } // Adding Tones foreach (var jsonTone in attr.Tones) { if (jsonTone == null) { continue; } if (!data.TonesRS2014.OfType <Tone2014>().Any(t => t.Key == jsonTone.Key)) { data.TonesRS2014.Add(jsonTone); } } // Adding Arrangement data.Arrangements.Add(new Arrangement(attr, xmlFile)); } else { var voc = new Arrangement(); voc.Name = ArrangementName.Vocals; voc.ArrangementType = ArrangementType.Vocal; voc.SongXml = new SongXML { File = xmlFile }; voc.SongFile = new SongFile { File = "" }; voc.Sng2014 = Sng2014HSL.Sng2014File.ConvertXML(xmlFile, ArrangementType.Vocal); voc.ScrollSpeed = 20; // Adding Arrangement data.Arrangements.Add(voc); } } //Get Files var ddsFiles = Directory.GetFiles(unpackedDir, "*_256.dds", SearchOption.AllDirectories); if (ddsFiles.Length > 0) { data.AlbumArtPath = ddsFiles[0]; } var sourceAudioFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories); var targetAudioFiles = new List <string>(); foreach (var file in sourceAudioFiles) { var newFile = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), Path.GetExtension(file))); if (targetPlatform.IsConsole != file.GetAudioPlatform().IsConsole) { OggFile.ConvertAudioPlatform(file, newFile); targetAudioFiles.Add(newFile); } else { targetAudioFiles.Add(file); } } if (targetAudioFiles.Count() <= 0) { throw new InvalidDataException("Audio files not found."); } string audioPath = null, audioPreviewPath = null; FileInfo a = new FileInfo(targetAudioFiles[0]); FileInfo b = null; if (targetAudioFiles.Count() == 2) { b = new FileInfo(targetAudioFiles[1]); if (a.Length > b.Length) { audioPath = a.FullName; audioPreviewPath = b.FullName; } else { audioPath = b.FullName; audioPreviewPath = a.FullName; } } else { audioPath = a.FullName; } data.OggPath = audioPath; //Make Audio preview with expected name when rebuild if (!String.IsNullOrEmpty(audioPreviewPath)) { var newPreviewFileName = Path.Combine(Path.GetDirectoryName(audioPath), String.Format("{0}_preview{1}", Path.GetFileNameWithoutExtension(audioPath), Path.GetExtension(audioPath))); File.Move(audioPreviewPath, newPreviewFileName); data.OggPreviewPath = newPreviewFileName; } var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories); if (appidFile.Length > 0) { data.AppId = File.ReadAllText(appidFile[0]); } return(data); }
/// <summary> /// Transforms unpacked Song into project-like folder structure. /// </summary> /// <returns>Output folder path.</returns> /// <param name="unpackedDir">Unpacked dir.</param> public static string DoLikeProject(string unpackedDir) { const string EOF = "EOF"; const string KIT = "Toolkit"; string outdir, eofdir, kitdir; string SongName = "SongName"; // Get name for a new folder var jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories); var attr = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value; SongName = attr.FullName.Split('_')[0]; //Create dir sruct outdir = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", attr.ArtistName.GetValidSortName(), attr.SongName.GetValidSortName()).Replace(" ", "-")); eofdir = Path.Combine(outdir, EOF); kitdir = Path.Combine(outdir, KIT); attr = null; //dispose // Don't work in same dir if (Directory.Exists(outdir)) { if (outdir == unpackedDir) { return(unpackedDir); } DirectoryExtension.SafeDelete(outdir); } Directory.CreateDirectory(outdir); Directory.CreateDirectory(eofdir); Directory.CreateDirectory(kitdir); string[] xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories); string[] sngFiles = Directory.GetFiles(unpackedDir, "*vocals.sng", SearchOption.AllDirectories); foreach (var json in jsonFiles) { var Name = Path.GetFileNameWithoutExtension(json); var xmlFile = xmlFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == Name); var sngFile = sngFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == Name); //Move all pair JSON\XML File.Move(json, Path.Combine(kitdir, Name + ".json")); File.Move(xmlFile, Path.Combine(eofdir, Name + ".xml")); if (Name.EndsWith("vocals", StringComparison.Ordinal)) { File.Move(sngFile, Path.Combine(kitdir, Name + ".sng")); } } //Move all art_size.dds to KIT folder var ArtFiles = Directory.GetFiles(unpackedDir, "album_*_*.dds", SearchOption.AllDirectories); if (ArtFiles.Any()) { foreach (var art in ArtFiles) { File.Move(art, Path.Combine(kitdir, Path.GetFileName(art))); } } var LyricArt = Directory.GetFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories); if (LyricArt.Any()) { foreach (var art in LyricArt) { File.Move(art, Path.Combine(kitdir, Path.GetFileName(art))); } } //Move ogg to EOF folder + rename var OggFiles = Directory.GetFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories); if (!OggFiles.Any()) { throw new InvalidDataException("Audio files not found."); } //TODO: read names from bnk and rename. var a0 = new FileInfo(OggFiles[0]); FileInfo b0 = null; if (OggFiles.Length == 2) { b0 = new FileInfo(OggFiles[1]); if (a0.Length > b0.Length) { File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg")); File.Move(b0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg")); } else { File.Move(b0.FullName, Path.Combine(eofdir, SongName + ".ogg")); File.Move(a0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg")); } } else { File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg")); } //Move wem to KIT folder + rename var WemFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories); if (!WemFiles.Any()) { throw new InvalidDataException("Audio files not found."); } var a1 = new FileInfo(WemFiles[0]); FileInfo b1 = null; if (WemFiles.Length == 2) { b1 = new FileInfo(WemFiles[1]); if (a1.Length > b1.Length) { File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem")); File.Move(b1.FullName, Path.Combine(kitdir, SongName + "_preview.wem")); } else { File.Move(b1.FullName, Path.Combine(kitdir, SongName + ".wem")); File.Move(a1.FullName, Path.Combine(kitdir, SongName + "_preview.wem")); } } else { File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem")); } //Move Appid for correct template generation. var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories); if (appidFile.Length > 0) { File.Move(appidFile[0], Path.Combine(kitdir, Path.GetFileName(appidFile[0]))); } //Move toolkit.version var toolkitVersion = Directory.GetFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories); if (toolkitVersion.Length > 0) { File.Move(toolkitVersion[0], Path.Combine(kitdir, Path.GetFileName(toolkitVersion[0]))); } //Remove old folder DirectoryExtension.SafeDelete(unpackedDir); return(outdir); }
/// <summary> /// Loads required DLC info from folder. /// </summary> /// <returns>The DLCPackageData info.</returns> /// <param name="unpackedDir">Unpacked dir.</param> /// <param name="targetPlatform">Target platform.</param> public static DLCPackageData LoadFromFolder(string unpackedDir, Platform targetPlatform) { var data = new DLCPackageData(); data.GameVersion = GameVersion.RS2014; data.SignatureType = PackageMagic.CON; //Arrangements / Tones data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); //Source platform + audio files var targetAudioFiles = new List <string>(); var sourceAudioFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories); Platform sourcePlatform = new Platform(GamePlatform.Pc, GameVersion.None); foreach (var file in sourceAudioFiles) { var newFile = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), Path.GetExtension(file))); if (targetPlatform.IsConsole != (sourcePlatform = file.GetAudioPlatform()).IsConsole) { OggFile.ConvertAudioPlatform(file, newFile); targetAudioFiles.Add(newFile); } else { targetAudioFiles.Add(file); } } if (!targetAudioFiles.Any()) { throw new InvalidDataException("Audio files not found."); } //Load files var jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories); foreach (var json in jsonFiles) { var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value; var xmlName = attr.SongXml.Split(':')[3]; var xmlFile = Directory.GetFiles(unpackedDir, xmlName + ".xml", SearchOption.AllDirectories)[0]; if (attr.Phrases != null) { if (data.SongInfo == null) { // Fill Package Data data.Name = attr.DLCKey; data.Volume = attr.SongVolume; data.PreviewVolume = (float)(attr.PreviewVolume ?? data.Volume); // Fill SongInfo data.SongInfo = new SongInfo(); data.SongInfo.SongDisplayName = attr.SongName; data.SongInfo.SongDisplayNameSort = attr.SongNameSort; data.SongInfo.Album = attr.AlbumName; data.SongInfo.SongYear = attr.SongYear ?? 0; data.SongInfo.Artist = attr.ArtistName; data.SongInfo.ArtistSort = attr.ArtistNameSort; data.SongInfo.AverageTempo = (int)attr.SongAverageTempo; } // Adding Tones foreach (var jsonTone in attr.Tones) { if (jsonTone == null) { continue; } var key = jsonTone.Key; if (data.TonesRS2014.All(t => t.Key != key)) { data.TonesRS2014.Add(jsonTone); } } // Adding Arrangement data.Arrangements.Add(new Arrangement(attr, xmlFile)); } else { var voc = new Arrangement(); voc.Name = attr.JapaneseVocal == true ? ArrangementName.JVocals : ArrangementName.Vocals; voc.ArrangementType = ArrangementType.Vocal; voc.ScrollSpeed = 20; voc.SongXml = new SongXML { File = xmlFile }; voc.SongFile = new SongFile { File = "" }; voc.CustomFont = attr.JapaneseVocal == true; // Get symbols stuff, write plain sng to disk. var fontSng = Directory.GetFiles(unpackedDir, xmlName + ".sng", SearchOption.AllDirectories)[0]; var vocSng = Sng2014HSL.Sng2014File.LoadFromFile(fontSng, sourcePlatform); if (vocSng.IsCustomFont()) { voc.CustomFont = true; voc.FontSng = fontSng; vocSng.WriteChartData(fontSng, new Platform(GamePlatform.Pc, GameVersion.None)); } voc.Sng2014 = Sng2014HSL.Sng2014File.ConvertXML(xmlFile, ArrangementType.Vocal, voc.FontSng); // Adding Arrangement data.Arrangements.Add(voc); } } //Get DDS Files + hacky reuse if exist var ddsFiles = Directory.GetFiles(unpackedDir, "album_*.dds", SearchOption.AllDirectories); if (ddsFiles.Length > 0) { var ddsFilesC = new List <DDSConvertedFile>(); foreach (var file in ddsFiles) { switch (Path.GetFileNameWithoutExtension(file).Split('_')[2]) { case "256": data.AlbumArtPath = file; ddsFilesC.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "128": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; case "64": ddsFilesC.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = file, destinationFile = file.CopyToTempFile(".dds") }); break; } } data.ArtFiles = ddsFilesC; } // Lyric Art var LyricArt = Directory.GetFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories); if (LyricArt.Any()) { data.LyricArtPath = LyricArt[0]; } //Get other files string audioPath = null, audioPreviewPath = null; FileInfo a = new FileInfo(targetAudioFiles[0]); FileInfo b = null; if (targetAudioFiles.Count == 2) { b = new FileInfo(targetAudioFiles[1]); if (a.Length > b.Length) { audioPath = a.FullName; audioPreviewPath = b.FullName; } else { audioPath = b.FullName; audioPreviewPath = a.FullName; } } else { audioPath = a.FullName; } data.OggPath = audioPath; //Make Audio preview with expected name when rebuild if (!String.IsNullOrEmpty(audioPreviewPath)) { var newPreviewFileName = Path.Combine(Path.GetDirectoryName(audioPath), String.Format("{0}_preview{1}", Path.GetFileNameWithoutExtension(audioPath), Path.GetExtension(audioPath))); File.Move(audioPreviewPath, newPreviewFileName); data.OggPreviewPath = newPreviewFileName; } //AppID var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories); if (appidFile.Length > 0) { data.AppId = File.ReadAllText(appidFile[0]); } //Package version var versionFile = Directory.GetFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories); if (versionFile.Length > 0) { data.PackageVersion = GeneralExtensions.ReadPackageVersion(versionFile[0]); } else { data.PackageVersion = "1"; } return(data); }
/// <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); }
private static void UpdateManifest2014(string songDirectory, Platform platform) { if (platform.version != GameVersion.RS2014) { return; } var hsanFiles = Directory.EnumerateFiles(songDirectory, "*.hsan", SearchOption.AllDirectories).ToList(); if (!hsanFiles.Any()) { throw new DataException("Error: could not find any hsan file"); } if (hsanFiles.Count > 1) { throw new DataException("Error: there is more than one hsan file"); } var manifestHeader = new ManifestHeader2014 <AttributesHeader2014>(platform); var hsanFile = hsanFiles.First(); var jsonFiles = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories).ToList(); var xmlFiles = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories).ToList(); //var songFiles = xmlFiles.Where(x => !x.ToLower().Contains("showlight") && !x.ToLower().Contains("vocal")).ToList(); //var vocalFiles = xmlFiles.Where(x => x.ToLower().Contains("vocal")).ToList(); foreach (var xmlFile in xmlFiles) { var xmlName = Path.GetFileNameWithoutExtension(xmlFile); if (xmlName.ToLower().Contains("showlight")) { continue; } var json = jsonFiles.FirstOrDefault(name => Path.GetFileNameWithoutExtension(name) == xmlName); if (String.IsNullOrEmpty(json)) { continue; } var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.First().Value.First().Value; if (!xmlName.ToLower().Contains("vocal")) { var manifestFunctions = new ManifestFunctions(platform.version); var xmlContent = Song2014.LoadFromFile(xmlFile); attr.PhraseIterations = new List <Manifest.PhraseIteration>(); manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version); attr.Phrases = new List <Manifest.Phrase>(); manifestFunctions.GeneratePhraseData(attr, xmlContent); attr.Sections = new List <Manifest.Section>(); manifestFunctions.GenerateSectionData(attr, xmlContent); attr.Tuning = new TuningStrings(); manifestFunctions.GenerateTuningData(attr, xmlContent); attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent); } // else { // TODO: good place to update vocals } // write updated json file var attributeDictionary = new Dictionary <string, Attributes2014> { { "Attributes", attr } }; var manifest = new Manifest2014 <Attributes2014>(); manifest.Entries.Add(attr.PersistentID, attributeDictionary); manifest.SaveToFile(json); // update manifestHeader (hsan) entry var attributeHeaderDictionary = new Dictionary <string, AttributesHeader2014> { { "Attributes", new AttributesHeader2014(attr) } }; if (platform.IsConsole) { // One for each arrangements (Xbox360/PS3) manifestHeader = new ManifestHeader2014 <AttributesHeader2014>(platform); manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary); } else { manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary); } } // write updated hsan file manifestHeader.SaveToFile(hsanFile); }