Пример #1
0
 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);
            }
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        // 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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        /// <summary>
        /// Unpack the specified File, returns unpacked dir.
        /// </summary>
        /// <param name="sourceFileName">Source file path.</param>
        /// <param name="savePath">Save path.</param>
        /// <param name="decodeAudio">If set to <c>true</c> decode audio.</param>
        /// <param name="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);
        }
Пример #8
0
        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);
                }
            }
        }
Пример #9
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);
        }
Пример #10
0
        /// <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);
        }
Пример #12
0
        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;
        }
Пример #13
0
        // 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);
        }