void DestroyOggFile() { if (oggFile != null) { oggFile.Dispose(); oggFile = null; } }
public static AudioBuffer LoadSound(string filePath) { if (GlobalNetwork.IsServer) { return(null); } filePath = GLoader.GetContentRelativePath(Path.Combine("Sounds", filePath)); AudioBuffer buffer; if (sound.TryGetValue(filePath, out buffer)) { return(buffer); } else { if (!File.Exists(filePath)) { return(null); } string ext = Path.GetExtension(filePath); switch (ext) { case ".wav": buffer = new WavFile(filePath); break; case ".ogg": buffer = new OggFile(filePath); break; default: throw new IOException($"Audio files with extension {ext} are not supported!"); } sound.Add(filePath, buffer); return(buffer); } }
/// <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); }
// Load RS1 CDLC into PackageCreator public static DLCPackageData RS1LoadFromFolder(string unpackedDir, Platform targetPlatform, bool convert) { var data = new DLCPackageData(); data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); data.Tones = new List <Tone>(); data.GameVersion = (convert ? GameVersion.RS2014 : GameVersion.RS2012); data.SignatureType = PackageMagic.CON; // set default volumes data.Volume = -6.5F; // default maybe too quite data.PreviewVolume = data.Volume; //Load song manifest var songsManifestJson = Directory.GetFiles(unpackedDir, "songs.manifest.json", SearchOption.AllDirectories); if (songsManifestJson.Length < 1) { throw new DataException("No songs.manifest.json file found."); } if (songsManifestJson.Length > 1) { throw new DataException("More than one songs.manifest.json file found."); } var attr = new List <Attributes>(); var songsManifest = Manifest.Manifest.LoadFromFile(songsManifestJson[0]).Entries.ToArray(); for (int smIndex = 0; smIndex < songsManifest.Count(); smIndex++) { var smData = songsManifest[smIndex].Value.ToArray()[0].Value; attr.Add(smData); } if (attr.FirstOrDefault() == null) { throw new DataException("songs.manifest.json file did not parse correctly."); } // Fill SongInfo data.SongInfo = new SongInfo(); data.SongInfo.SongDisplayName = attr.FirstOrDefault().SongName; data.SongInfo.SongDisplayNameSort = attr.FirstOrDefault().SongNameSort; data.SongInfo.Album = attr.FirstOrDefault().AlbumName; data.SongInfo.SongYear = (attr.FirstOrDefault().SongYear == 0 ? 2012 : attr.FirstOrDefault().SongYear); data.SongInfo.Artist = attr.FirstOrDefault().ArtistName; data.SongInfo.ArtistSort = attr.FirstOrDefault().ArtistNameSort; data.Name = attr.FirstOrDefault().SongKey; //Load tone manifest, even poorly formed tone_bass.manifest.json var toneManifestJson = Directory.GetFiles(unpackedDir, "*tone*.manifest.json", SearchOption.AllDirectories); if (toneManifestJson.Length < 1) { throw new DataException("No tone.manifest.json file found."); } // toolkit produces multiple tone.manifest.json files when packing RS1 CDLC files // rather than change toolkit behavior just merge manifest files for now if (toneManifestJson.Length > 1) { var mergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Union }; JObject toneObject1 = new JObject(); foreach (var tone in toneManifestJson) { JObject toneObject2 = JObject.Parse(File.ReadAllText(tone)); //(toneObject1.SelectToken("Entries") as JArray).Merge(toneObject2.SelectToken("Entries")); toneObject1.Merge(toneObject2, mergeSettings); } toneManifestJson = new string[1]; toneManifestJson[0] = Path.Combine(unpackedDir, "merged.tone.manifest.json"); string json = JsonConvert.SerializeObject(toneObject1, Formatting.Indented); File.WriteAllText(toneManifestJson[0], json); } var tones2014 = new List <Tone2014>(); var tones = new List <Tone>(); var toneManifest = Manifest.Tone.Manifest.LoadFromFile(toneManifestJson[0]); for (int tmIndex = 0; tmIndex < toneManifest.Entries.Count(); tmIndex++) { var tmData = toneManifest.Entries[tmIndex]; tones.Add(tmData); } data.Tones = tones; // Load AggregateGraph.nt var songDir = Path.Combine(unpackedDir, data.Name); if (targetPlatform.platform == GamePlatform.XBox360) { songDir = Path.Combine(unpackedDir, "Root", data.Name); } var aggFile = Directory.GetFiles(songDir, "*.nt", SearchOption.TopDirectoryOnly)[0]; var aggGraphData = AggregateGraph.AggregateGraph.ReadFromFile(aggFile); // Load Exports\Songs\*.xblock var xblockDir = Path.Combine(songDir, "Exports\\Songs"); var xblockFile = Directory.GetFiles(xblockDir, "*.xblock", SearchOption.TopDirectoryOnly)[0]; // xblockFile = "D:\\Temp\\Mapping\\songs.xblock"; var songsXblock = XblockX.LoadFromFile(xblockFile); // create project map for cross referencing arrangements with tones var projectMap = AggregateGraph.AggregateGraph.ProjectMap(aggGraphData, songsXblock, toneManifest); // Load xml arrangements var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories); if (xmlFiles.Length <= 0) { throw new DataException("Can not find any XML arrangement files"); } foreach (var xmlFile in xmlFiles) { if (xmlFile.ToLower().Contains("metadata")) { continue; } // some poorly formed RS1 CDLC use just "vocal" if (xmlFile.ToLower().Contains("vocal")) { // Add Vocal Arrangement data.Arrangements.Add(new Arrangement { Name = ArrangementName.Vocals, ArrangementType = ArrangementType.Vocal, ScrollSpeed = 20, SongXml = new SongXML { File = xmlFile }, SongFile = new SongFile { File = "" }, CustomFont = false }); } else { var attr2014 = new Attributes2014(); var rsSong = new Song(); var rsSong2014 = new Song2014(); // optimized tone matching effort using project mapping algo var result = projectMap.First(m => String.Equals(Path.GetFileName(m.SongXmlPath), Path.GetFileName(xmlFile), StringComparison.CurrentCultureIgnoreCase)); if (result.Tones.Count != 1) { throw new DataException("Invalid RS1 CDLC Tones Data"); } var arrangement = attr.First(s => s.SongXml.ToLower().Contains(result.LLID));//FIXME: Sequence contains no matching element issue var tone = tones.First(t => t.Key == result.Tones[0]); using (var obj1 = new Rs1Converter()) { rsSong = obj1.XmlToSong(xmlFile); data.SongInfo.AverageTempo = (int)obj1.AverageBPM(rsSong); } if (arrangement.Tuning == "E Standard") { rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 } } ; else if (arrangement.Tuning == "DropD") { rsSong.Tuning = new TuningStrings { String0 = -2, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 } } ; else if (arrangement.Tuning == "OpenG") { rsSong.Tuning = new TuningStrings { String0 = -2, String1 = -2, String2 = 0, String3 = 0, String4 = 0, String5 = -2 } } ; else if (arrangement.Tuning == "EFlat") { rsSong.Tuning = new TuningStrings { String0 = -1, String1 = -1, String2 = -1, String3 = -1, String4 = -1, String5 = -1 } } ; else // default to standard tuning { arrangement.Tuning = "E Standard"; rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 }; } // save/write the changes to xml file using (var obj1 = new Rs1Converter()) obj1.SongToXml(rsSong, xmlFile, true); if (convert) { using (var obj1 = new Rs1Converter()) tones2014.Add(obj1.ToneToTone2014(tone, rsSong)); } // load attr2014 with RS1 mapped values for use by Arrangement() attr2014.Tone_Base = tone.Name; attr2014.ArrangementName = arrangement.ArrangementName; attr2014.CentOffset = 0; attr2014.DynamicVisualDensity = new List <float>() { 2 }; attr2014.SongPartition = arrangement.SongPartition; attr2014.PersistentID = IdGenerator.Guid().ToString(); attr2014.MasterID_RDV = RandomGenerator.NextInt(); attr2014.ArrangementProperties = new SongArrangementProperties2014(); // processing order is important - CAREFUL // RouteMask None = 0, Lead = 1, Rhythm = 2, Any = 3, Bass = 4 // XML file names are usually meaningless to arrangement determination if (arrangement.ArrangementName.ToLower().Contains("lead") || rsSong.Arrangement.ToLower().Contains("lead")) { attr2014.ArrangementName = "Lead"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead; attr2014.ArrangementProperties.PathLead = 1; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("rhythm") || rsSong.Arrangement.ToLower().Contains("rhythm")) // || rsSong.Arrangement.ToLower().Contains("guitar")) { attr2014.ArrangementName = "Rhythm"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Rhythm; attr2014.ArrangementProperties.PathLead = 0; attr2014.ArrangementProperties.PathRhythm = 1; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("combo") || rsSong.Arrangement.ToLower().Contains("combo")) { attr2014.ArrangementName = "Combo"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = arrangement.EffectChainName.ToLower().Contains("lead") ? (int)RouteMask.Lead : (int)RouteMask.Rhythm; attr2014.ArrangementProperties.PathLead = arrangement.EffectChainName.ToLower().Contains("lead") ? 1 : 0; attr2014.ArrangementProperties.PathRhythm = arrangement.EffectChainName.ToLower().Contains("lead") ? 0 : 1; attr2014.ArrangementProperties.PathBass = 0; } else if (arrangement.ArrangementName.ToLower().Contains("bass") || rsSong.Arrangement.ToLower().Contains("bass")) { attr2014.ArrangementName = "Bass"; attr2014.ArrangementType = (int)ArrangementType.Bass; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Bass; attr2014.ArrangementProperties.PathLead = 0; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 1; } else { // default to Lead arrangement attr2014.ArrangementName = "Lead"; attr2014.ArrangementType = (int)ArrangementType.Guitar; attr2014.ArrangementProperties.RouteMask = (int)RouteMask.Lead; attr2014.ArrangementProperties.PathLead = 1; attr2014.ArrangementProperties.PathRhythm = 0; attr2014.ArrangementProperties.PathBass = 0; Console.WriteLine("RS1->RS2 CDLC Conversion defaulted to 'Lead' arrangement"); } if (convert) // RS1 -> RS2 magic { using (var obj1 = new Rs1Converter()) rsSong2014 = obj1.SongToSong2014(rsSong); // update ArrangementProperties rsSong2014.ArrangementProperties.RouteMask = attr2014.ArrangementProperties.RouteMask; rsSong2014.ArrangementProperties.PathLead = attr2014.ArrangementProperties.PathLead; rsSong2014.ArrangementProperties.PathRhythm = attr2014.ArrangementProperties.PathRhythm; rsSong2014.ArrangementProperties.PathBass = attr2014.ArrangementProperties.PathBass; rsSong2014.ArrangementProperties.StandardTuning = (arrangement.Tuning == "E Standard" ? 1 : 0); // <note time="58.366" linkNext="0" accent="0" bend="0" fret="7" hammerOn="0" harmonic="0" hopo="0" ignore="0" leftHand="-1" mute="0" palmMute="0" pluck="-1" pullOff="0" slap="-1" slideTo="-1" string="3" sustain="0.108" tremolo="0" harmonicPinch="0" pickDirection="0" rightHand="-1" slideUnpitchTo="-1" tap="0" vibrato="0" /> if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Bend != 0))) { rsSong2014.ArrangementProperties.Bends = 1; } if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Hopo != 0))) { rsSong2014.ArrangementProperties.Hopo = 1; } if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.SlideTo != -1))) { rsSong2014.ArrangementProperties.Slides = 1; } if (rsSong2014.Levels.Any(sl => sl.Notes.Any(sln => sln.Sustain > 0))) { rsSong2014.ArrangementProperties.Sustain = 1; } // fixing times that are off var lastEbeatsTime = rsSong2014.Ebeats[rsSong2014.Ebeats.Length - 1].Time; var lastPhraseIterationsTime = rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time; // tested ... not source of in game hangs // confirm last PhraseIterations time is less than last Ebeats time if (lastPhraseIterationsTime > lastEbeatsTime) { rsSong2014.PhraseIterations[rsSong2014.PhraseIterations.Length - 1].Time = lastEbeatsTime; rsSong2014.Sections[rsSong2014.Sections.Length - 1].StartTime = lastEbeatsTime; } // tested ... not source of in game hangs // confirm SongLength at least equals last Ebeats time if (rsSong2014.SongLength < lastEbeatsTime) { rsSong2014.SongLength = lastEbeatsTime; } using (var obj2 = new Rs2014Converter()) obj2.Song2014ToXml(rsSong2014, xmlFile, true); } // Adding Song Arrangement try { data.Arrangements.Add(new Arrangement(attr2014, xmlFile)); } catch (Exception ex) { // mainly for the benefit of convert2012 CLI users Console.WriteLine(@"This CDLC could not be auto converted." + Environment.NewLine + "You can still try manually adding the arrangements and assets." + Environment.NewLine + ex.Message); } } } if (convert) { // get rid of duplicate tone names tones2014 = tones2014.Where(p => p.Name != null) .GroupBy(p => p.Name).Select(g => g.First()).ToList(); data.TonesRS2014 = tones2014; } //Get Album Artwork DDS Files var artFiles = Directory.GetFiles(unpackedDir, "*.dds", SearchOption.AllDirectories); if (artFiles.Length < 1) { throw new DataException("No Album Artwork file found."); } if (artFiles.Length > 1) { throw new DataException("More than one Album Artwork file found."); } var targetArtFiles = new List <DDSConvertedFile>(); data.AlbumArtPath = artFiles[0]; targetArtFiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = artFiles[0], destinationFile = artFiles[0].CopyToTempFile(".dds") }); data.ArtFiles = targetArtFiles; //Audio files var targetAudioFiles = new List <string>(); var audioFiles = Directory.GetFiles(unpackedDir, "*.ogg", SearchOption.AllDirectories); if (audioFiles.Length < 1) { throw new DataException("No Audio file found."); } if (audioFiles.Length > 2) { throw new DataException("Too many Audio files found."); } int i; for (i = 0; i < audioFiles.Length; i++) { if (convert && audioFiles[i].Contains("_fixed.ogg")) // use it { break; } if (!convert && !audioFiles[i].Contains("_fixed.ogg")) { break; } } // FIXME: platform specific decode is broken var sourcePlatform = unpackedDir.GetPlatform(); if (targetPlatform.IsConsole != (sourcePlatform = audioFiles[i].GetAudioPlatform()).IsConsole) { var newFile = Path.Combine(Path.GetDirectoryName(audioFiles[i]), String.Format("{0}_cap.ogg", Path.GetFileNameWithoutExtension(audioFiles[i]))); OggFile.ConvertAudioPlatform(audioFiles[i], newFile); audioFiles[i] = newFile; } targetAudioFiles.Add(audioFiles[i]); if (!targetAudioFiles.Any()) { throw new DataException("Audio file not found."); } var a = new FileInfo(audioFiles[i]); data.OggPath = a.FullName; //AppID if (!sourcePlatform.IsConsole) { if (!convert) { var appidFile = Directory.GetFiles(unpackedDir, "*APP_ID*", SearchOption.AllDirectories); if (appidFile.Length > 0) { data.AppId = File.ReadAllText(appidFile[0]); } } else { data.AppId = "248750"; } } try { // 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 = ""; } } catch { } if (convert) { data.Tones = null; } return(data); }
private void Converter(TextBox control, ConverterType converterType) { InputAudioFiles = null; txtOgg2FixHdr.Text = String.Empty; txtWwiseConvert.Text = String.Empty; txtWwise2Ogg.Text = String.Empty; txtAudio2Wem.Text = String.Empty; using (var fd = new OpenFileDialog()) { fd.Multiselect = true; fd.Filter = "Wwise 2010.3.3 OGG files (*.ogg)|*.ogg"; if (converterType == ConverterType.Revorb || converterType == ConverterType.WEM) { fd.Filter += "|Wwise 2013 WEM files (*.wem)|*.wem"; } else if (converterType == ConverterType.Ogg2Wem) { fd.Filter = "Vobis Ogg or Wave files (*.ogg, *.wav)|*.ogg; *.wav"; } fd.ShowDialog(); if (!fd.FileNames.Any()) { return; } InputAudioFiles = fd.FileNames; Dictionary <string, string> errorFiles = new Dictionary <string, string>(); List <string> successFiles = new List <string>(); foreach (var file in InputAudioFiles) { try { var extension = Path.GetExtension(file); var outputFileName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), ".ogg")); switch (converterType) { case ConverterType.HeaderFix: txtOgg2FixHdr.Text = file; using (FileStream fl = File.Create(outputFileName)) OggFile.ConvertOgg(file).CopyTo(fl); break; case ConverterType.Revorb: txtWwise2Ogg.Text = file; OggFile.Revorb(file, outputFileName, Path.GetDirectoryName(Application.ExecutablePath), (extension == ".ogg") ? OggFile.WwiseVersion.Wwise2010 : OggFile.WwiseVersion.Wwise2013); break; case ConverterType.WEM: txtWwiseConvert.Text = file; outputFileName = Path.ChangeExtension(outputFileName, Path.GetExtension(file)); OggFile.ConvertAudioPlatform(file, outputFileName); break; case ConverterType.Ogg2Wem: txtAudio2Wem.Text = file; OggFile.Convert2Wem(file, (int)audioQualityBox.Value, (long)Convert.ToDouble(lblChorusTime.Text) * 1000); break; } successFiles.Add(file); } catch (Exception ex) { errorFiles.Add(file, ex.Message); } } if (errorFiles.Count <= 0 && successFiles.Count > 0) { MessageBox.Show("Conversion complete!", MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (errorFiles.Count > 0 && successFiles.Count > 0) { StringBuilder alertMessage = new StringBuilder( "Conversion complete with errors." + Environment.NewLine + Environment.NewLine); alertMessage.AppendLine( "Files converted with success:" + Environment.NewLine); foreach (var sFile in successFiles) { alertMessage.AppendLine(String.Format("File: {0}", sFile)); } alertMessage.AppendLine("Files converted with error:" + Environment.NewLine); foreach (var eFile in errorFiles) { alertMessage.AppendLine(String.Format("File: {0}; error: {1}", eFile.Key, eFile.Value)); } MessageBox.Show(alertMessage.ToString(), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { StringBuilder alertMessage = new StringBuilder( "Conversion complete with errors." + Environment.NewLine); alertMessage.AppendLine( "Files converted with error: " + Environment.NewLine); foreach (var eFile in errorFiles) { alertMessage.AppendLine(String.Format("File: {0}, error: {1}", eFile.Key, eFile.Value)); } MessageBox.Show(alertMessage.ToString(), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
/// <summary> /// Convert wem archive entries to ogg files /// </summary> /// <param name="wems"></param> /// <param name="audioOggPath"></param> /// <param name="previewOggPath"></param> /// <returns></returns> public bool ConvertWemEntries(List <Entry> wems, string audioOggPath, string previewOggPath = "") { // TODO: Debug this untested revised code before first use bool result = false; if (wems.Count > 1) { wems.Sort((e1, e2) => { if (e1.Length < e2.Length) { return(1); } if (e1.Length > e2.Length) { return(-1); } return(0); }); } if (wems.Count > 0) { var top = wems[0]; // wem audio with internal TOC path var tempAudioPath = Path.Combine(Path.GetTempPath(), top.Name); top.Data.Position = 0; using (var fs = File.Create(tempAudioPath)) { top.Data.CopyTo(fs); try { OggFile.Revorb(tempAudioPath, audioOggPath, Path.GetExtension(tempAudioPath).GetWwiseVersion()); result = true; } catch { result = false; } } } if (!String.IsNullOrEmpty(previewOggPath) && result && wems.Count > 0) { var bottom = wems.Last(); var tempAudioPath = Path.Combine(Path.GetTempPath(), bottom.Name); bottom.Data.Position = 0; using (var fs = File.Create(tempAudioPath)) { bottom.Data.CopyTo(fs); try { OggFile.Revorb(tempAudioPath, previewOggPath, Path.GetExtension(tempAudioPath).GetWwiseVersion()); result = true; } catch { result = false; } } } return(result); }
/// <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); }
private void Converter(TextBox control, ConverterType converterType) { InputAudioFiles = null; using (var fd = new OpenFileDialog()) { fd.Multiselect = true; fd.Filter = "Wwise 2010.3.3 OGG files (*.ogg)|*.ogg"; if (converterType == ConverterType.Revorb) { fd.Filter += "|Wwise 2013 WEM files (*.wem)|*.wem"; } else if (converterType == ConverterType.WEM) { fd.Filter += "|Wwise 2013 WEM files (*.wem)|*.wem"; //fd.Multiselect = false; } fd.ShowDialog(); if (fd.FileNames.Count() <= 0) { MessageBox.Show("The selected directory has no valid file inside!", MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } string path = Path.GetDirectoryName(fd.FileName); switch (converterType) { case ConverterType.HeaderFix: inputOggTextBox.Text = path; break; case ConverterType.Revorb: inputAudioRocksmithTextBox.Text = path; break; case ConverterType.WEM: InputWemConversionTextbox.Text = path; break; } InputAudioFiles = fd.FileNames; Dictionary <string, string> errorFiles = new Dictionary <string, string>(); List <string> successFiles = new List <string>(); foreach (var file in InputAudioFiles) { try { var extension = Path.GetExtension(file); var outputFileName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), ".ogg")); switch (converterType) { case ConverterType.HeaderFix: using (FileStream fl = File.Create(outputFileName)) { OggFile.ConvertOgg(file).CopyTo(fl); } break; case ConverterType.Revorb: OggFile.Revorb(file, outputFileName, Path.GetDirectoryName(Application.ExecutablePath), (extension == ".ogg") ? OggFile.WwiseVersion.Wwise2010 : OggFile.WwiseVersion.Wwise2013); break; case ConverterType.WEM: outputFileName = Path.ChangeExtension(outputFileName, Path.GetExtension(file)); OggFile.ConvertAudioPlatform(file, outputFileName); break; } successFiles.Add(file); } catch (Exception ex) { errorFiles.Add(file, ex.Message); } } if (errorFiles.Count <= 0 && successFiles.Count > 0) { MessageBox.Show("Conversion complete!", MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information); } else if (errorFiles.Count > 0 && successFiles.Count > 0) { StringBuilder alertMessage = new StringBuilder( "Conversion complete with errors." + Environment.NewLine + Environment.NewLine); alertMessage.AppendLine( "Files converted with success:" + Environment.NewLine); foreach (var sFile in successFiles) { alertMessage.AppendLine(String.Format("File: {0}", sFile)); } alertMessage.AppendLine("Files converted with error:" + Environment.NewLine); foreach (var eFile in errorFiles) { alertMessage.AppendLine(String.Format("File: {0}; error: {1}", eFile.Key, eFile.Value)); } MessageBox.Show(alertMessage.ToString(), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { StringBuilder alertMessage = new StringBuilder( "Conversion complete with errors." + Environment.NewLine); alertMessage.AppendLine( "Files converted with error: " + Environment.NewLine); foreach (var eFile in errorFiles) { alertMessage.AppendLine(String.Format("File: {0}, error: {1}", eFile.Key, eFile.Value)); } MessageBox.Show(alertMessage.ToString(), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
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> /// 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); }
void CreateOggFile() { PreloadNativeLibraries(); DestroyOggFile(); var fileName = FileName.Value?.ResourceName; if (string.IsNullOrEmpty(fileName)) { return; } VirtualFileStream stream = null; try { stream = VirtualFile.Open(fileName); oggFile = new OggFile(); oggFile.Volume = Volume; bool sound3D = ParentContainer.Transform3D != null; // is UIContainer3D; oggFile.Init(stream, new MyVideoDriver(videoBuffer), new MyAudioDriver(), sound3D); } catch (Exception ex) { if (!noLogErrorAtLoading) { Log.Warning(string.Format("UIVideo: CreateOggFile: Error: {0} ({1}).", ex.Message, fileName)); } if (oggFile != null) { oggFile.Dispose(); oggFile = null; } if (stream != null) { stream.Dispose(); } return; } if (oggFile.VideoDriver == null) { oggFile.Dispose(); oggFile = null; } if (oggFile == null) { return; } UpdateOggFileSoundPosition(); oggFile.Pause = Pause; }
// Load RS1 CDLC into PackageCreator public static DLCPackageData RS1LoadFromFolder(string unpackedDir, Platform targetPlatform, bool convert) { var data = new DLCPackageData(); data.Arrangements = new List <Arrangement>(); data.TonesRS2014 = new List <Tone2014>(); data.Tones = new List <Tone>(); data.GameVersion = (convert ? GameVersion.RS2014 : GameVersion.RS2012); data.SignatureType = PackageMagic.CON; // set default volumes data.Volume = (float)-5.5; // - 7 default a little too quite data.PreviewVolume = data.Volume; //Load song manifest var songsManifestJson = Directory.GetFiles(unpackedDir, "songs.manifest.json", SearchOption.AllDirectories); if (songsManifestJson.Length < 1) { throw new DataException("No songs.manifest.json file found."); } if (songsManifestJson.Length > 1) { throw new DataException("More than one songs.manifest.json file found."); } List <Attributes> attr = new List <Attributes>(); var songsManifest = Manifest.Manifest.LoadFromFile(songsManifestJson[0]).Entries.ToArray(); for (int smIndex = 0; smIndex < songsManifest.Count(); smIndex++) { var smData = songsManifest[smIndex].Value.ToArray()[0].Value; attr.Add(smData); } if (attr.FirstOrDefault() == null) { throw new DataException("songs.manifest.json file did not parse correctly."); } // Fill SongInfo data.SongInfo = new SongInfo(); data.SongInfo.SongDisplayName = attr.FirstOrDefault().SongName; data.SongInfo.SongDisplayNameSort = attr.FirstOrDefault().SongNameSort; data.SongInfo.Album = attr.FirstOrDefault().AlbumName; data.SongInfo.SongYear = (attr.FirstOrDefault().SongYear == 0 ? 2012 : attr.FirstOrDefault().SongYear); data.SongInfo.Artist = attr.FirstOrDefault().ArtistName; data.SongInfo.ArtistSort = attr.FirstOrDefault().ArtistNameSort; data.Name = attr.FirstOrDefault().SongKey; //Load tone manifest, even poorly formed tone_bass.manifest.json var toneManifestJson = Directory.GetFiles(unpackedDir, "*tone*.manifest.json", SearchOption.AllDirectories); if (toneManifestJson.Length < 1) { throw new DataException("No tone.manifest.json file found."); } // toolkit produces multiple tone.manifest.json files when packing RS1 CDLC files // rather than change toolkit behavior just merge manifest files for now if (toneManifestJson.Length > 1) { var mergeSettings = new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Union }; JObject toneObject1 = new JObject(); foreach (var tone in toneManifestJson) { JObject toneObject2 = JObject.Parse(File.ReadAllText(tone)); //(toneObject1.SelectToken("Entries") as JArray).Merge(toneObject2.SelectToken("Entries")); toneObject1.Merge(toneObject2, mergeSettings); } toneManifestJson = new string[1]; toneManifestJson[0] = Path.Combine(unpackedDir, "merged.tone.manifest"); string json = JsonConvert.SerializeObject(toneObject1, Formatting.Indented); File.WriteAllText(toneManifestJson[0], json); } List <Tone> tones = new List <Tone>(); var toneManifest = Manifest.Tone.Manifest.LoadFromFile(toneManifestJson[0]); for (int tmIndex = 0; tmIndex < toneManifest.Entries.Count(); tmIndex++) { var tmData = toneManifest.Entries[tmIndex]; tones.Add(tmData); } data.Tones = tones; // Load xml arrangements var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories); if (xmlFiles.Length <= 0) { throw new DataException("Can not find any XML arrangement files"); } List <Tone2014> tones2014 = new List <Tone2014>(); foreach (var xmlFile in xmlFiles) { if (xmlFile.ToLower().Contains("metadata")) // skip DF file { continue; } // some poorly formed RS1 CDLC use just "vocal" if (xmlFile.ToLower().Contains("vocal")) { var voc = new Arrangement(); voc.Name = ArrangementName.Vocals; voc.ArrangementType = ArrangementType.Vocal; voc.ScrollSpeed = 20; voc.SongXml = new SongXML { File = xmlFile }; voc.SongFile = new SongFile { File = "" }; voc.CustomFont = false; // Add Vocal Arrangement data.Arrangements.Add(voc); } else { Attributes2014 attr2014 = new Attributes2014(); Song rsSong = new Song(); bool foundToneForArrangement = false; using (var obj1 = new Rs1Converter()) { rsSong = obj1.XmlToSong(xmlFile); data.SongInfo.AverageTempo = (int)obj1.AverageBPM(rsSong); } // matchup rsSong, songs.manifest, and tone.manifest files foreach (var arrangement in attr) { // apply best guesstimate matching, RS1 CDLC are very inconsistent // TODO: improve accuracy possibly by matching .xblock data string xmlArr = rsSong.Arrangement.ToLowerInvariant(); // var matchLead = Regex.Match(xmlArr.ToLower(), "^lead$", RegexOptions.IgnoreCase); // if(matchLead.Success) if (xmlArr.ToLower().Contains("guitar") && !xmlArr.ToLower().Equals("lead") && !xmlArr.ToLower().Equals("rhythm") && !xmlArr.ToLower().Equals("combo") && !xmlArr.ToLower().Equals("bass")) { if (xmlArr.ToUpper().Equals("PART REAL_GUITAR_22")) // { if (arrangement.ArrangementName.ToLower().Contains("combo")) { rsSong.Arrangement = arrangement.ArrangementName = "Rhythm"; } else { rsSong.Arrangement = arrangement.ArrangementName = "Lead"; } } else { if (arrangement.ArrangementName.ToLower().Contains("combo")) { rsSong.Arrangement = arrangement.ArrangementName = "Rhythm"; } else { rsSong.Arrangement = arrangement.ArrangementName = "Lead"; } } } if (xmlArr.ToLower().Contains("lead") && arrangement.ArrangementName.ToLower().Contains("rhythm")) { rsSong.Arrangement = arrangement.ArrangementName = "Lead"; } if (xmlArr.ToLower().Contains("rhythm") && arrangement.ArrangementName.ToLower().Contains("lead")) { rsSong.Arrangement = arrangement.ArrangementName = "Rhythm"; } if (xmlArr.ToLower().Contains("lead")) { if (!arrangement.ArrangementName.ToLower().Contains("lead")) { continue; } } if (xmlArr.ToLower().Contains("rhythm")) { if (!arrangement.ArrangementName.ToLower().Contains("rhythm")) { continue; } } if (xmlArr.ToLower().Contains("combo")) { if (!arrangement.ArrangementName.ToLower().Contains("combo")) { continue; } } if (xmlArr.ToLower().Contains("bass")) { if (!arrangement.ArrangementName.ToLower().Contains("bass")) { continue; } } if (rsSong.Part == arrangement.SongPartition || tones.Count == 1) // this is inaccurate for some { foreach (var tone in tones) // tone.manifest { if (String.IsNullOrEmpty(arrangement.EffectChainName)) { arrangement.EffectChainName = "Default"; } if (arrangement.EffectChainName.ToLower() == tone.Key.ToLower() || tones.Count == 1) // ok { if (convert) { using (var obj1 = new Rs1Converter()) tones2014.Add(obj1.ToneToTone2014(tone)); // added for consistent naming tone.Name = tones2014[tones2014.Count - 1].Name; tone.Key = tones2014[tones2014.Count - 1].Key; } // load attr2014 with RS1 mapped values for use by Arrangement() attr2014.Tone_Base = tone.Name; attr2014.ArrangementName = arrangement.ArrangementName; attr2014.CentOffset = 0; attr2014.DynamicVisualDensity = new List <float>() { 2 }; attr2014.SongPartition = arrangement.SongPartition; attr2014.PersistentID = IdGenerator.Guid().ToString(); attr2014.MasterID_RDV = RandomGenerator.NextInt(); attr2014.ArrangementProperties = new SongArrangementProperties2014(); if (arrangement.ArrangementName.ToLower().Contains("lead")) { attr2014.ArrangementType = 0; attr2014.ArrangementProperties.RouteMask = 1; } else if (arrangement.ArrangementName.ToLower().Contains("rhythm")) { attr2014.ArrangementType = 1; attr2014.ArrangementProperties.RouteMask = 2; } else if (arrangement.ArrangementName.ToLower().Contains("combo")) { attr2014.ArrangementType = 2; attr2014.ArrangementProperties.RouteMask = arrangement.EffectChainName.ToLower().Contains("lead") ? 1 : 2; } else if (arrangement.ArrangementName.ToLower().Contains("bass")) { attr2014.ArrangementType = 3; attr2014.ArrangementProperties.RouteMask = 4; } else { // some RS1 CDLC do not have a valid ArrangementName if (rsSong.Arrangement.ToLower().Contains("guitar")) { attr2014.ArrangementName = "Lead"; attr2014.ArrangementType = 0; attr2014.ArrangementProperties.RouteMask = 1; } else if (rsSong.Arrangement.ToLower().Contains("bass")) { attr2014.ArrangementName = "Bass"; attr2014.ArrangementType = 3; attr2014.ArrangementProperties.RouteMask = 4; } else // default to rhythm { attr2014.ArrangementName = "Rhythm"; attr2014.ArrangementType = 1; attr2014.ArrangementProperties.RouteMask = 2; } } if (arrangement.Tuning == "E Standard") { rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 } } ; else if (arrangement.Tuning == "DropD") { rsSong.Tuning = new TuningStrings { String0 = -2, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 } } ; else if (arrangement.Tuning == "OpenG") { rsSong.Tuning = new TuningStrings { String0 = -2, String1 = -2, String2 = 0, String3 = 0, String4 = 0, String5 = -2 } } ; else if (arrangement.Tuning == "EFlat") { rsSong.Tuning = new TuningStrings { String0 = -1, String1 = -1, String2 = -1, String3 = -1, String4 = -1, String5 = -1 } } ; else // default to standard tuning { rsSong.Tuning = new TuningStrings { String0 = 0, String1 = 0, String2 = 0, String3 = 0, String4 = 0, String5 = 0 } }; foundToneForArrangement = true; break; } } } if (foundToneForArrangement) { break; } } if (!foundToneForArrangement) { Console.WriteLine(@"Could not determine the arrangement tone pairing"); } // write the tones to file using (var obj1 = new Rs1Converter()) obj1.SongToXml(rsSong, xmlFile, true); if (convert) // RS1 -> RS2 { Song2014 rsSong2014 = new Song2014(); using (var obj1 = new Rs1Converter()) rsSong2014 = obj1.SongToSong2014(rsSong); using (var obj2 = new Rs2014Converter()) obj2.Song2014ToXml(rsSong2014, xmlFile, true); } // Adding Song Arrangement try { data.Arrangements.Add(new Arrangement(attr2014, xmlFile)); } catch (Exception ex) { // mainly for the benifit of convert2012 CLI users Console.WriteLine(@"This CDLC could not be auto converted." + Environment.NewLine + "You can still try manually adding the arrangements and assests." + Environment.NewLine + ex.Message); } } } data.TonesRS2014 = tones2014; //Get Album Artwork DDS Files var artFiles = Directory.GetFiles(unpackedDir, "*.dds", SearchOption.AllDirectories); if (artFiles.Length < 1) { throw new DataException("No Album Artwork file found."); } if (artFiles.Length > 1) { throw new DataException("More than one Album Artwork file found."); } var targetArtFiles = new List <DDSConvertedFile>(); data.AlbumArtPath = artFiles[0]; targetArtFiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = artFiles[0], destinationFile = artFiles[0].CopyToTempFile(".dds") }); data.ArtFiles = targetArtFiles; //Audio files var targetAudioFiles = new List <string>(); var audioFiles = Directory.GetFiles(unpackedDir, "*.ogg", SearchOption.AllDirectories); if (audioFiles.Length < 1) { throw new DataException("No Audio file found."); } if (audioFiles.Length > 2) { throw new DataException("Too many Audio files found."); } int i; for (i = 0; i < audioFiles.Length; i++) { if (convert && audioFiles[i].Contains("_fixed.ogg")) // use it { break; } if (!convert && !audioFiles[i].Contains("_fixed.ogg")) { break; } } var sourcePlatform = unpackedDir.GetPlatform(); if (targetPlatform.IsConsole != (sourcePlatform = audioFiles[i].GetAudioPlatform()).IsConsole) { var newFile = Path.Combine(Path.GetDirectoryName(audioFiles[i]), String.Format("{0}_cap.ogg", Path.GetFileNameWithoutExtension(audioFiles[i]))); OggFile.ConvertAudioPlatform(audioFiles[i], newFile); audioFiles[i] = newFile; } targetAudioFiles.Add(audioFiles[i]); if (!targetAudioFiles.Any()) { throw new DataException("Audio file not found."); } FileInfo a = new FileInfo(audioFiles[i]); data.OggPath = a.FullName; //AppID if (!convert) { var appidFile = Directory.GetFiles(unpackedDir, "*APP_ID*", SearchOption.AllDirectories); if (appidFile.Length > 0) { data.AppId = File.ReadAllText(appidFile[0]); } } else { data.AppId = "248750"; } //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"; } if (convert) { data.Tones = null; } return(data); }