public Arrangement() { Id = IdGenerator.Guid(); MasterId = (ArrangementType == ArrangementType.Vocal || ArrangementType == ArrangementType.ShowLight) ? 1 : RandomGenerator.NextInt(); }
// 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); }