private void convertSngXmlButton_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(ConverterSngXmlFile))
            {
                MessageBox.Show(String.Format("File not found: {0}: ", ConverterSngXmlFile), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                sngXmlTB.Focus();
                return;
            }

            if (sng2xmlRadio.Checked)
            {
                if (String.IsNullOrEmpty(ConverterManifestFile))
                {
                    MessageBox.Show("No manifest file was entered. The song xml file will be generated without song informations like song title, album, artist, tone names, etc.", MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                Attributes2014 att = null;
                if (ConverterArrangementType != ArrangementType.Vocal && !String.IsNullOrEmpty(ConverterManifestFile))
                {
                    att = Manifest2014 <Attributes2014> .LoadFromFile(ConverterManifestFile).Entries.ToArray()[0].Value.ToArray()[0].Value;
                }

                var sng = Sng2014File.LoadFromFile(ConverterSngXmlFile, ConverterPlatform);

                var outputFile = Path.Combine(Path.GetDirectoryName(ConverterSngXmlFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(ConverterSngXmlFile)));
                using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite))
                {
                    dynamic xml = null;

                    if (ConverterArrangementType == ArrangementType.Vocal)
                    {
                        xml = new Vocals(sng);
                    }
                    else
                    {
                        xml = new Song2014(sng, att ?? null);
                    }

                    xml.Serialize(outputStream);

                    MessageBox.Show(String.Format("XML file was generated! {0}It was saved on same location of sng file specified.", Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else if (xml2sngRadio.Checked)
            {
                var outputFile = Path.Combine(Path.GetDirectoryName(ConverterSngXmlFile), String.Format("{0}.sng", Path.GetFileNameWithoutExtension(ConverterSngXmlFile)));

                using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) {
                    Sng2014File sng = Sng2014File.ConvertXML(ConverterSngXmlFile, ConverterArrangementType);
                    sng.WriteSng(outputStream, ConverterPlatform);
                }

                MessageBox.Show(String.Format("SNG file was generated! {0}It was saved on same location of xml file specified.", Environment.NewLine), MESSAGEBOX_CAPTION, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        // this method will work for Song Packs too!
        public IEnumerable <Manifest2014 <Attributes2014> > ExtractJsonManifests()
        {
            var sw = new Stopwatch();

            sw.Restart();

            // every song contains gamesxblock but may not contain showlights.xml
            var xblockEntries = _archive.TOC.Where(x => x.Name.StartsWith("gamexblocks/nsongs") && x.Name.EndsWith(".xblock")).ToList();

            if (!xblockEntries.Any())
            {
                throw new Exception("Could not find valid xblock file in archive.");
            }

            var jsonData = new List <Manifest2014 <Attributes2014> >();

            // this foreach loop addresses song packs otherwise it is only done one time
            foreach (var xblockEntry in xblockEntries)
            {
                // CAREFUL with use of Contains and Replace to avoid creating duplicates
                var strippedName = xblockEntry.Name.Replace(".xblock", "").Replace("gamexblocks/nsongs", "");
                if (strippedName.Contains("_fcp_dlc"))
                {
                    strippedName = strippedName.Replace("fcp_dlc", "");
                }

                var jsonEntries = _archive.TOC.Where(x => x.Name.StartsWith("manifests/songs") &&
                                                     x.Name.EndsWith(".json") && x.Name.Contains(strippedName)).OrderBy(x => x.Name).ToList();

                // looping through song multiple times gathering each arrangement
                foreach (var jsonEntry in jsonEntries)
                {
                    var dataObj = new Manifest2014 <Attributes2014>();

                    _archive.InflateEntry(jsonEntry);
                    jsonEntry.Data.Position = 0;
                    var ms = new MemoryStream();
                    using (var reader = new StreamReader(ms, new UTF8Encoding(), false, 65536)) //4Kb is default alloc size for windows .. 64Kb is default PSARC alloc
                    {
                        jsonEntry.Data.Position = 0;
                        jsonEntry.Data.CopyTo(ms);
                        ms.Position = 0;
                        var jsonObj = JObject.Parse(reader.ReadToEnd());
                        dataObj = JsonConvert.DeserializeObject <Manifest2014 <Attributes2014> >(jsonObj.ToString());
                    }

                    jsonData.Add(dataObj);
                }
            }

            sw.Stop();
            GlobalExtension.ShowProgress(String.Format("{0} parsing json manifest entries took: {1} (msec)", Path.GetFileName(_filePath), sw.ElapsedMilliseconds));
            return(jsonData);
        }
Esempio n. 3
0
        private static List <Tone2014> ReadFromManifest(string manifestFilePath)
        {
            List <Tone2014> tones = new List <Tone2014>();

            Attributes2014 jsonManifestAttributes = Manifest2014 <Attributes2014> .LoadFromFile(manifestFilePath).Entries.ToArray()[0].Value.ToArray()[0].Value;

            if (jsonManifestAttributes.ArrangementName != ArrangementName.Vocals.ToString() && jsonManifestAttributes.Tones != null)
            {
                tones.AddRange(jsonManifestAttributes.Tones);
            }

            return(tones);
        }
        private static void UpdateManifest2014(string songDirectory, Platform platform)
        {
            // UPDATE MANIFEST (RS2014)
            if (platform.version == GameVersion.RS2014)
            {
                var xmlFiles  = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories);
                var jsonFiles = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories);
                foreach (var xml in xmlFiles)
                {
                    var xmlName = Path.GetFileNameWithoutExtension(xml);
                    if (xmlName.ToUpperInvariant().Contains("SHOWLIGHT"))
                    {
                        continue;
                    }
                    if (xmlName.ToUpperInvariant().Contains("VOCAL"))
                    {
                        continue;//TODO: Re-generate vocals manifest.
                    }
                    string json = jsonFiles.Where(name => Path.GetFileNameWithoutExtension(name) == xmlName).FirstOrDefault();
                    if (!String.IsNullOrEmpty(json))
                    {
                        var xmlContent = Song2014.LoadFromFile(xml);
                        var manifest   = new Manifest2014 <Attributes2014>();
                        var attr       = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.First().Value.First().Value;

                        var manifestFunctions = new ManifestFunctions(platform.version);

                        attr.PhraseIterations = new List <Manifest.PhraseIteration>();
                        manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                        attr.Phrases = new List <Manifest.Phrase>();
                        manifestFunctions.GeneratePhraseData(attr, xmlContent);

                        attr.Sections = new List <Manifest.Section>();
                        manifestFunctions.GenerateSectionData(attr, xmlContent);

                        attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);

                        var attributeDictionary = new Dictionary <string, Attributes2014> {
                            { "Attributes", attr }
                        };
                        manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                        manifest.SaveToFile(json);
                    }
                }
            }
        }
Esempio n. 5
0
        private static void GeneratePedalsRS2014(string inputDir)
        {
            //inputDir like "......\ROCKSMITH\gears_Pc\manifests\gears" (gears_Pc is gears.psarc unpacked)
            var gearsJsonFiles = Directory.EnumerateFiles(inputDir, "*.json");
            List <ToolkitPedal> toolkitPedals = new List <ToolkitPedal>();

            foreach (var file in gearsJsonFiles)
            {
                var gearManifest = Manifest2014 <RsToneRS2014> .LoadFromFile(file);

                foreach (var pedal in gearManifest.Entries)
                {
                    toolkitPedals.Add(pedal.Value["Attributes"].ToPedal());
                }
            }
            JsonSerializerSettings jss = new JsonSerializerSettings();

            jss.Formatting = Formatting.Indented;
            File.WriteAllText("pedals2014.json", JsonConvert.SerializeObject(toolkitPedals, jss));
        }
Esempio n. 6
0
        private int ApplyPackageDD(string file, string remSUS, string rampPath, out string consoleOutputPkg)
        {
            int  singleResult  = -1;
            bool exitedByError = false;

            consoleOutputPkg = String.Empty;
            var tmpDir      = Path.GetTempPath();
            var platform    = file.GetPlatform();
            var unpackedDir = Packer.Unpack(file, tmpDir, false, true, false);

            var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories);

            foreach (var xml in xmlFiles)
            {
                if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("vocal"))
                {
                    continue;
                }

                if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("showlight"))
                {
                    continue;
                }

                singleResult = ApplyDD(xml, remSUS, rampPath, out consoleOutputPkg, true, false);

                // UPDATE MANIFEST (RS2014) for update
                if (platform.version == RocksmithToolkitLib.GameVersion.RS2014)
                {
                    var json = Directory.GetFiles(unpackedDir, String.Format("*{0}.json", Path.GetFileNameWithoutExtension(xml)), SearchOption.AllDirectories);
                    if (json.Length > 0)
                    {
                        Attributes2014 attr = Manifest2014 <Attributes2014> .LoadFromFile(json[0]).Entries.ToArray()[0].Value.ToArray()[0].Value;

                        Song2014 xmlContent = Song2014.LoadFromFile(xml);

                        var manifestFunctions = new ManifestFunctions(platform.version);

                        attr.PhraseIterations = new List <PhraseIteration>();
                        manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                        attr.Phrases = new List <Phrase>();
                        manifestFunctions.GeneratePhraseData(attr, xmlContent);

                        attr.Sections = new List <Section>();
                        manifestFunctions.GenerateSectionData(attr, xmlContent);

                        attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);

                        var manifest            = new Manifest2014 <Attributes2014>();
                        var attributeDictionary = new Dictionary <string, Attributes2014> {
                            { "Attributes", attr }
                        };
                        manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                        manifest.SaveToFile(json[0]);
                    }
                }

                if (singleResult == 1)
                {
                    exitedByError = true;
                    break;
                }
                else if (singleResult == 2)
                {
                    consoleOutputPkg = String.Format("Arrangement file '{0}' => {1}", Path.GetFileNameWithoutExtension(xml), consoleOutputPkg);
                }
            }

            if (!exitedByError)
            {
                var newName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_{1}{2}",
                                                                                      Path.GetFileNameWithoutExtension(file).StripPlatformEndName().GetValidName(false).Replace("_DD", "").Replace("_NDD", ""), isNDD ? "NDD" :  "DD", platform.GetPathName()[2]));
                Packer.Pack(unpackedDir, newName, true, platform);
                DirectoryExtension.SafeDelete(unpackedDir);
            }
            return(singleResult);
        }
        private int ApplyPackageDD(string file, string remSUS, string rampPath, out string consoleOutputPkg)
        {
            int singleResult = -1;
            bool exitedByError = false;
            consoleOutputPkg = String.Empty;
            var tmpDir = Path.GetTempPath();
            var platform = file.GetPlatform();
            var unpackedDir = Packer.Unpack(file, tmpDir, false, true, false);

            var xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories);
            foreach (var xml in xmlFiles)
            {
                if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("vocal"))
                    continue;

                if (Path.GetFileNameWithoutExtension(xml).ToLower().Contains("showlight"))
                    continue;

                singleResult = ApplyDD(xml, remSUS, rampPath, out consoleOutputPkg, true, false);

                // UPDATE MANIFEST (RS2014) for update
                if (platform.version == RocksmithToolkitLib.GameVersion.RS2014) {
                    var json = Directory.GetFiles(unpackedDir, String.Format("*{0}.json", Path.GetFileNameWithoutExtension(xml)), SearchOption.AllDirectories);
                    if (json.Length > 0) {
                        Attributes2014 attr = Manifest2014<Attributes2014>.LoadFromFile(json[0]).Entries.ToArray()[0].Value.ToArray()[0].Value;
                        Song2014 xmlContent = Song2014.LoadFromFile(xml);

                        var manifestFunctions = new ManifestFunctions(platform.version);

                        attr.PhraseIterations = new List<PhraseIteration>();
                        manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                        attr.Phrases = new List<Phrase>();
                        manifestFunctions.GeneratePhraseData(attr, xmlContent);

                        attr.Sections = new List<Section>();
                        manifestFunctions.GenerateSectionData(attr, xmlContent);

                        attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);

                        var manifest = new Manifest2014<Attributes2014>();
                        var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attr } };
                        manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                        manifest.SaveToFile(json[0]);
                    }
                }

                if (singleResult == 1)
                {
                    exitedByError = true;
                    break;
                }
                else if (singleResult == 2)
                    consoleOutputPkg = String.Format("Arrangement file '{0}' => {1}", Path.GetFileNameWithoutExtension(xml), consoleOutputPkg);
            }

            if (!exitedByError)
            {
                var newName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_{1}{2}",
                    Path.GetFileNameWithoutExtension(file).StripPlatformEndName().GetValidName(false).Replace("_DD", "").Replace("_NDD",""), isNDD ? "NDD" :  "DD", platform.GetPathName()[2]));
                Packer.Pack(unpackedDir, newName, true, platform);
                DirectoryExtension.SafeDelete(unpackedDir);
            }
            return singleResult;
        }
        /// <summary>
        /// Unpack the specified File, returns unpacked dir.
        /// </summary>
        /// <param name="sourceFileName">Source file path.</param>
        /// <param name="savePath">Save path.</param>
        /// <param name="decodeAudio">If set to <c>true</c> decode audio.</param>
        /// <param name="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);
        }
        // this method will work for Song Packs too!
        public IEnumerable<Manifest2014<Attributes2014>> ExtractJsonManifests()
        {
            var sw = new Stopwatch();
            sw.Restart();

            // every song contains gamesxblock but may not contain showlights.xml
            var xblockEntries = _archive.TOC.Where(x => x.Name.StartsWith("gamexblocks/nsongs") && x.Name.EndsWith(".xblock")).ToList();
            if (!xblockEntries.Any())
                throw new Exception("Could not find valid xblock file in archive.");

            var jsonData = new List<Manifest2014<Attributes2014>>();
            // this foreach loop addresses song packs otherwise it is only done one time
            foreach (var xblockEntry in xblockEntries)
            {
                var strippedName = xblockEntry.Name.Replace(".xblock", "").Replace("gamexblocks/nsongs/", "");
                if (strippedName.Contains("_fcp_dlc"))
                    strippedName = strippedName.Replace("_fcp_dlc", "");

                var jsonEntries = _archive.TOC.Where(x => x.Name.StartsWith("manifests/songs") && x.Name.EndsWith(".json") && x.Name.Contains(strippedName)).OrderBy(x => x.Name).ToList();

                // looping through song multiple times gathering each arrangement
                foreach (var jsonEntry in jsonEntries)
                {
                    var dataObj = new Manifest2014<Attributes2014>();

                    _archive.InflateEntry(jsonEntry);
                    jsonEntry.Data.Position = 0;
                    var ms = new MemoryStream();
                    using (var reader = new StreamReader(ms, new UTF8Encoding(), false, 65536)) //4Kb is default alloc size for windows .. 64Kb is default PSARC alloc
                    {
                        jsonEntry.Data.Position = 0;
                        jsonEntry.Data.CopyTo(ms);
                        ms.Position = 0;
                        var jsonObj = JObject.Parse(reader.ReadToEnd());
                        dataObj = JsonConvert.DeserializeObject<Manifest2014<Attributes2014>>(jsonObj.ToString());
                    }

                    jsonData.Add(dataObj);
                }
            }

            sw.Stop();
            GlobalExtension.ShowProgress(String.Format("{0} parsing json manifest entries took: {1} (msec)", Path.GetFileName(_filePath), sw.ElapsedMilliseconds));
            return jsonData;
        }
        private static void GenerateRS2014SongPsarc(MemoryStream output, DLCPackageData info, Platform platform)
        {
            var dlcName = info.Name.ToLower();

            {
                var packPsarc = new PSARC.PSARC();

                // Stream objects
                Stream soundStream = null,
                       soundPreviewStream = null,
                       rsenumerableRootStream = null,
                       rsenumerableSongStream = null;

                try {
                    // ALBUM ART
                    var ddsfiles = info.ArtFiles;

                    if (ddsfiles == null) {
                        string albumArtPath;
                        if (File.Exists(info.AlbumArtPath)) {
                            albumArtPath = info.AlbumArtPath;
                        } else {
                            using (var albumArtStream = new MemoryStream(Resources.albumart2014_256))
                            {
                                albumArtPath = GeneralExtensions.GetTempFileName(".dds");
                                albumArtStream.WriteFile(albumArtPath);
                                TMPFILES_ART.Add(albumArtPath);
                            }
                        }

                        ddsfiles = new List<DDSConvertedFile>();
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });

                        // Convert to DDS
                        ToDDS(ddsfiles);

                        // Save for reuse
                        info.ArtFiles = ddsfiles;
                    }

                    foreach (var dds in ddsfiles)
                        packPsarc.AddEntry(String.Format("gfxassets/album_art/album_{0}_{1}.dds", dlcName, dds.sizeX), new FileStream(dds.destinationFile, FileMode.Open, FileAccess.Read, FileShare.Read));

                    //Lyrics Font Texture
                    if (File.Exists(info.LyricsTex))
                        packPsarc.AddEntry(String.Format("assets/ui/lyrics/{0}/lyrics_{0}.dds", dlcName), new FileStream(info.LyricsTex, FileMode.Open, FileAccess.Read, FileShare.Read));

                    // AUDIO
                    var audioFile = info.OggPath;
                    if (File.Exists(audioFile))
                        if (platform.IsConsole != audioFile.GetAudioPlatform().IsConsole)
                            soundStream = OggFile.ConvertAudioPlatform(audioFile);
                        else
                            soundStream = File.OpenRead(audioFile);
                    else
                        throw new InvalidOperationException(String.Format("Audio file '{0}' not found.", audioFile));

                    // AUDIO PREVIEW
                    var previewAudioFile = info.OggPreviewPath;
                    if (File.Exists(previewAudioFile))
                        if (platform.IsConsole != previewAudioFile.GetAudioPlatform().IsConsole)
                            soundPreviewStream = OggFile.ConvertAudioPlatform(previewAudioFile);
                        else
                            soundPreviewStream = File.OpenRead(previewAudioFile);
                    else
                        soundPreviewStream = soundStream;

                    // FLAT MODEL
                    rsenumerableRootStream = new MemoryStream(Resources.rsenumerable_root);
                    packPsarc.AddEntry("flatmodels/rs/rsenumerable_root.flat", rsenumerableRootStream);
                    rsenumerableSongStream = new MemoryStream(Resources.rsenumerable_song);
                    packPsarc.AddEntry("flatmodels/rs/rsenumerable_song.flat", rsenumerableSongStream);

                    using (var toolkitVersionStream = new MemoryStream())
                    using (var appIdStream = new MemoryStream())
                    using (var packageListStream = new MemoryStream())
                    using (var soundbankStream = new MemoryStream())
                    using (var soundbankPreviewStream = new MemoryStream())
                    using (var aggregateGraphStream = new MemoryStream())
                    using (var manifestHeaderHSANStream = new MemoryStream())
                    using (var manifestHeaderHSONStreamList = new DisposableCollection<Stream>())
                    using (var manifestStreamList = new DisposableCollection<Stream>())
                    using (var arrangementStream = new DisposableCollection<Stream>())
                    using (var showlightStream = new MemoryStream())
                    using (var xblockStream = new MemoryStream())
                    {
                        // TOOLKIT VERSION
                        GenerateToolkitVersion(toolkitVersionStream, info.PackageVersion);
                        packPsarc.AddEntry("toolkit.version", toolkitVersionStream);

                        // APP ID
                        if (!platform.IsConsole)
                        {
                            GenerateAppId(appIdStream, info.AppId, platform);
                            packPsarc.AddEntry("appid.appid", appIdStream);
                        }

                        if (platform.platform == GamePlatform.XBox360) {
                            var packageListWriter = new StreamWriter(packageListStream);
                            packageListWriter.Write(dlcName);
                            packageListWriter.Flush();
                            packageListStream.Seek(0, SeekOrigin.Begin);
                            string packageList = "PackageList.txt";
                            packageListStream.WriteTmpFile(packageList, platform);
                        }

                        // SOUNDBANK
                        var soundbankFileName = String.Format("song_{0}", dlcName);
                        var audioFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name, soundStream, soundbankStream, info.Volume, platform);
                        packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankFileName), soundbankStream);
                        packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioFileNameId), soundStream);

                        // SOUNDBANK PREVIEW
                        var soundbankPreviewFileName = String.Format("song_{0}_preview", dlcName);
                        dynamic audioPreviewFileNameId;
                        var previewVolume = (info.PreviewVolume != null) ? (float)info.PreviewVolume : info.Volume;
                        if (!soundPreviewStream.Equals(soundStream))
                            audioPreviewFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name + "_Preview", soundPreviewStream, soundbankPreviewStream, previewVolume, platform, true);
                        else
                            audioPreviewFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name + "_Preview", soundPreviewStream, soundbankPreviewStream, info.Volume, platform, true, true);
                        packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankPreviewFileName), soundbankPreviewStream);
                        if (!soundPreviewStream.Equals(soundStream)) packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioPreviewFileNameId), soundPreviewStream);

                        // AGGREGATE GRAPH
                        var aggregateGraphFileName = String.Format("{0}_aggregategraph.nt", dlcName);
                        var aggregateGraph = new AggregateGraph2014(info, platform);
                        aggregateGraph.Serialize(aggregateGraphStream);
                        aggregateGraphStream.Flush();
                        aggregateGraphStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(aggregateGraphFileName, aggregateGraphStream);

                        var manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
                        var songPartition = new SongPartition();
                        var songPartitionCount = new SongPartition();

                        foreach (var arrangement in info.Arrangements)
                        {
                            var arrangementFileName = songPartition.GetArrangementFileName(arrangement.Name, arrangement.ArrangementType).ToLower();

                            // GAME SONG (SNG)
                            UpdateToneDescriptors(info);
                            GenerateSNG(arrangement, platform);
                            var sngSongFile = File.OpenRead(arrangement.SongFile.File);
                            arrangementStream.Add(sngSongFile);
                            packPsarc.AddEntry(String.Format("songs/bin/{0}/{1}_{2}.sng", platform.GetPathName()[1].ToLower(), dlcName, arrangementFileName), sngSongFile);

                            // XML SONG
                            var xmlSongFile = File.OpenRead(arrangement.SongXml.File);
                            arrangementStream.Add(xmlSongFile);
                            packPsarc.AddEntry(String.Format("songs/arr/{0}_{1}.xml", dlcName, arrangementFileName), xmlSongFile);

                            // MANIFEST
                            var manifest = new Manifest2014<Attributes2014>();
                            var attribute = new Attributes2014(arrangementFileName, arrangement, info, platform);
                            if (arrangement.ArrangementType != Sng.ArrangementType.Vocal)
                            {
                                attribute.SongPartition = songPartitionCount.GetSongPartition(arrangement.Name, arrangement.ArrangementType);
                                if (attribute.SongPartition > 1)
                                { // Make the second arrangement with the same arrangement type as ALTERNATE arrangement ingame
                                    attribute.Representative = 0;
                                    attribute.ArrangementProperties.Represent = 0;
                                }
                            }
                            var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attribute } };
                            manifest.Entries.Add(attribute.PersistentID, attributeDictionary);
                            var manifestStream = new MemoryStream();
                            manifestStreamList.Add(manifestStream);
                            manifest.Serialize(manifestStream);
                            manifestStream.Seek(0, SeekOrigin.Begin);

                            var jsonPathPC = "manifests/songs_dlc_{0}/{0}_{1}.json";
                            var jsonPathConsole = "manifests/songs_dlc/{0}_{1}.json";
                            packPsarc.AddEntry(String.Format((platform.IsConsole ? jsonPathConsole : jsonPathPC), dlcName, arrangementFileName), manifestStream);

                            // MANIFEST HEADER
                            var attributeHeaderDictionary = new Dictionary<string, AttributesHeader2014> { { "Attributes", new AttributesHeader2014(attribute) } };

                            if (platform.IsConsole) {
                                // One for each arrangements (Xbox360/PS3)
                                manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
                                manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary);
                                var manifestHeaderStream = new MemoryStream();
                                manifestHeaderHSONStreamList.Add(manifestHeaderStream);
                                manifestHeader.Serialize(manifestHeaderStream);
                                manifestStream.Seek(0, SeekOrigin.Begin);
                                packPsarc.AddEntry(String.Format("manifests/songs_dlc/{0}_{1}.hson", dlcName, arrangementFileName), manifestHeaderStream);
                            } else {
                                // One for all arrangements (PC/Mac)
                                manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary);
                            }
                        }

                        if (!platform.IsConsole) {
                            manifestHeader.Serialize(manifestHeaderHSANStream);
                            manifestHeaderHSANStream.Seek(0, SeekOrigin.Begin);
                            packPsarc.AddEntry(String.Format("manifests/songs_dlc_{0}/songs_dlc_{0}.hsan", dlcName), manifestHeaderHSANStream);
                        }

                        // SHOWLIGHT
                        Showlights showlight = new Showlights(info);
                        showlight.Serialize(showlightStream);
                        if(showlightStream.CanRead)
                            packPsarc.AddEntry(String.Format("songs/arr/{0}_showlights.xml", dlcName), showlightStream);

                        // XBLOCK
                        GameXblock<Entity2014> game = GameXblock<Entity2014>.Generate2014(info, platform);
                        game.SerializeXml(xblockStream);
                        xblockStream.Flush();
                        xblockStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(String.Format("gamexblocks/nsongs/{0}.xblock", dlcName), xblockStream);

                        // WRITE PACKAGE
                        packPsarc.Write(output, !platform.IsConsole);
                        output.Flush();
                        output.Seek(0, SeekOrigin.Begin);
                        output.WriteTmpFile(String.Format("{0}.psarc", dlcName), platform);
                    }
                } catch (Exception ex) {
                    throw ex;
                } finally {
                    // Dispose all objects
                    if (soundStream != null)
                        soundStream.Dispose();
                    if (soundPreviewStream != null)
                        soundPreviewStream.Dispose();
                    if (rsenumerableRootStream != null)
                        rsenumerableRootStream.Dispose();
                    if (rsenumerableSongStream != null)
                        rsenumerableSongStream.Dispose();
                    DeleteTmpFiles(TMPFILES_SNG);
                    DeleteTmpFiles(TMPFILES_ART);
                }
            }
        }
        private static void GenerateRS2014InlayPsarc(MemoryStream output, DLCPackageData info, Platform platform)
        {
            var dlcName = info.Inlay.DLCSixName;
            // TODO updateProgress remotely from here
            {
                var packPsarc = new PSARC.PSARC();

                // Stream objects
                Stream rsenumerableRootStream = null,
                       rsenumerableGuitarStream = null;

                try {
                    // ICON/INLAY FILES
                    var ddsfiles = info.ArtFiles;

                    if (ddsfiles == null) {
                        string iconPath;
                        if (File.Exists(info.Inlay.IconPath)) {
                            iconPath = info.Inlay.IconPath;
                        } else {
                            using (var iconStream = new MemoryStream(Resources.cgm_default_icon)) {
                                iconPath = Path.ChangeExtension(Path.GetTempFileName(), ".png");
                                iconStream.WriteFile(iconPath);
                                TMPFILES_ART.Add(iconPath);
                            }
                        }

                        string inlayPath;
                        if (File.Exists(info.Inlay.InlayPath)) {
                            inlayPath = info.Inlay.InlayPath;
                        } else {
                            using (var inlayStream = new MemoryStream(Resources.cgm_default_inlay)) {
                                inlayPath = GeneralExtensions.GetTempFileName(".png");
                                inlayStream.WriteFile(inlayPath);
                                TMPFILES_ART.Add(inlayPath);
                            }
                        }

                        ddsfiles = new List<DDSConvertedFile>();
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = iconPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = iconPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = iconPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 512, sizeY = 512, sourceFile = iconPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                        ddsfiles.Add(new DDSConvertedFile() { sizeX = 1024, sizeY = 512, sourceFile = inlayPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });

                        // Convert to DDS
                        ToDDS(ddsfiles, DLCPackageType.Inlay);

                        // Save for reuse
                        info.ArtFiles = ddsfiles;
                    }

                    foreach (var dds in ddsfiles)
                        if (dds.sizeX == 1024)
                            packPsarc.AddEntry(String.Format("assets/gameplay/inlay/inlay_{0}.dds", dlcName), new FileStream(dds.destinationFile, FileMode.Open, FileAccess.Read, FileShare.Read));
                        else
                            packPsarc.AddEntry(String.Format("gfxassets/rewards/guitar_inlays/reward_inlay_{0}_{1}.dds", dlcName, dds.sizeX), new FileStream(dds.destinationFile, FileMode.Open, FileAccess.Read, FileShare.Read));

                    // FLAT MODEL
                    rsenumerableRootStream = new MemoryStream(Resources.rsenumerable_root);
                    packPsarc.AddEntry("flatmodels/rs/rsenumerable_root.flat", rsenumerableRootStream);
                    rsenumerableGuitarStream = new MemoryStream(Resources.rsenumerable_guitar);
                    packPsarc.AddEntry("flatmodels/rs/rsenumerable_guitars.flat", rsenumerableGuitarStream);

                    using (var toolkitVersionStream = new MemoryStream())
                    using (var appIdStream = new MemoryStream())
                    using (var packageListStream = new MemoryStream())
                    using (var aggregateGraphStream = new MemoryStream())
                    using (var manifestStreamList = new DisposableCollection<Stream>())
                    using (var manifestHeaderStream = new MemoryStream())
                    using (var nifStream = new MemoryStream())
                    using (var xblockStream = new MemoryStream()) {
                        // TOOLKIT VERSION
                        GenerateToolkitVersion(toolkitVersionStream);
                        packPsarc.AddEntry("toolkit.version", toolkitVersionStream);

                        // APP ID
                        if (!platform.IsConsole) {
                            GenerateAppId(appIdStream, info.AppId, platform);
                            packPsarc.AddEntry("appid.appid", appIdStream);
                        }

                        if (platform.platform == GamePlatform.XBox360) {
                            var packageListWriter = new StreamWriter(packageListStream);
                            packageListWriter.Write(dlcName);
                            packageListWriter.Flush();
                            packageListStream.Seek(0, SeekOrigin.Begin);
                            string packageList = "PackageList.txt";
                            packageListStream.WriteTmpFile(packageList, platform);
                        }

                        // AGGREGATE GRAPH
                        var aggregateGraphFileName = String.Format("{0}_aggregategraph.nt", dlcName);
                        var aggregateGraph = new AggregateGraph2014(info, platform, DLCPackageType.Inlay);
                        aggregateGraph.Serialize(aggregateGraphStream);
                        aggregateGraphStream.Flush();
                        aggregateGraphStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(aggregateGraphFileName, aggregateGraphStream);

                        // MANIFEST
                        var attribute = new InlayAttributes2014(info);
                        var attributeDictionary = new Dictionary<string, InlayAttributes2014> { { "Attributes", attribute } };
                        var manifest = new Manifest2014<InlayAttributes2014>(DLCPackageType.Inlay);
                        manifest.Entries.Add(attribute.PersistentID, attributeDictionary);
                        var manifestStream = new MemoryStream();
                        manifestStreamList.Add(manifestStream);
                        manifest.Serialize(manifestStream);
                        manifestStream.Seek(0, SeekOrigin.Begin);
                        var jsonPathPC = "manifests/songs_dlc_{0}/dlc_guitar_{0}.json";
                        var jsonPathConsole = "manifests/songs_dlc/dlc_guitar_{0}.json";
                        packPsarc.AddEntry(String.Format((platform.IsConsole ? jsonPathConsole : jsonPathPC), dlcName), manifestStream);

                        // MANIFEST HEADER
                        var attributeHeaderDictionary = new Dictionary<string, InlayAttributes2014> { { "Attributes", attribute } };
                        var manifestHeader = new ManifestHeader2014<InlayAttributes2014>(platform, DLCPackageType.Inlay);
                        manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary);
                        manifestHeader.Serialize(manifestHeaderStream);
                        manifestHeaderStream.Seek(0, SeekOrigin.Begin);
                        var hsanPathPC = "manifests/songs_dlc_{0}/dlc_{0}.hsan";
                        var hsonPathConsole = "manifests/songs_dlc/dlc_{0}.hson";
                        packPsarc.AddEntry(String.Format((platform.IsConsole ? hsonPathConsole : hsanPathPC), dlcName), manifestHeaderStream);

                        // XBLOCK
                        GameXblock<Entity2014> game = GameXblock<Entity2014>.Generate2014(info, platform, DLCPackageType.Inlay);
                        game.SerializeXml(xblockStream);
                        xblockStream.Flush();
                        xblockStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(String.Format("gamexblocks/nguitars/guitar_{0}.xblock", dlcName), xblockStream);

                        // INLAY NIF
                        InlayNif nif = new InlayNif(info);
                        nif.Serialize(nifStream);
                        nifStream.Flush();
                        nifStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(String.Format("assets/gameplay/inlay/{0}.nif", dlcName), nifStream);

                        // WRITE PACKAGE
                        packPsarc.Write(output, !platform.IsConsole);
                        output.Flush();
                        output.Seek(0, SeekOrigin.Begin);
                        output.WriteTmpFile(String.Format("{0}.psarc", dlcName), platform);
                    }
                } catch (Exception ex) {
                    throw ex;
                } finally {
                    // Dispose all objects
                    if (rsenumerableRootStream != null)
                        rsenumerableRootStream.Dispose();
                    if (rsenumerableGuitarStream != null)
                        rsenumerableGuitarStream.Dispose();
                    DeleteTmpFiles(TMPFILES_ART);
                }
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Transforms unpacked Song into project-like folder structure.
        /// </summary>
        /// <returns>Output folder path.</returns>
        /// <param name="unpackedDir">Unpacked dir.</param>
        public static string DoLikeProject(string unpackedDir)
        {
            const string EOF = "EOF";
            const string KIT = "Toolkit";
            string       outdir, eofdir, kitdir;
            string       SongName = "SongName";

            // Get name for a new folder
            var jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories);
            var attr      = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value;

            SongName = attr.FullName.Split('_')[0];

            //Create dir sruct
            outdir = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", attr.ArtistName.GetValidSortName(), attr.SongName.GetValidSortName()).Replace(" ", "-"));
            eofdir = Path.Combine(outdir, EOF);
            kitdir = Path.Combine(outdir, KIT);
            attr   = null; //dispose

            // Don't work in same dir
            if (Directory.Exists(outdir))
            {
                if (outdir == unpackedDir)
                {
                    return(unpackedDir);
                }
                DirectoryExtension.SafeDelete(outdir);
            }

            Directory.CreateDirectory(outdir);
            Directory.CreateDirectory(eofdir);
            Directory.CreateDirectory(kitdir);

            string[] xmlFiles = Directory.GetFiles(unpackedDir, "*.xml", SearchOption.AllDirectories);
            string[] sngFiles = Directory.GetFiles(unpackedDir, "*vocals.sng", SearchOption.AllDirectories);
            foreach (var json in jsonFiles)
            {
                var Name    = Path.GetFileNameWithoutExtension(json);
                var xmlFile = xmlFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == Name);
                var sngFile = sngFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == Name);

                //Move all pair JSON\XML
                File.Move(json, Path.Combine(kitdir, Name + ".json"));
                File.Move(xmlFile, Path.Combine(eofdir, Name + ".xml"));
                if (Name.EndsWith("vocals", StringComparison.Ordinal))
                {
                    File.Move(sngFile, Path.Combine(kitdir, Name + ".sng"));
                }
            }

            //Move all art_size.dds to KIT folder
            var ArtFiles = Directory.GetFiles(unpackedDir, "album_*_*.dds", SearchOption.AllDirectories);

            if (ArtFiles.Any())
            {
                foreach (var art in ArtFiles)
                {
                    File.Move(art, Path.Combine(kitdir, Path.GetFileName(art)));
                }
            }
            var LyricArt = Directory.GetFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories);

            if (LyricArt.Any())
            {
                foreach (var art in LyricArt)
                {
                    File.Move(art, Path.Combine(kitdir, Path.GetFileName(art)));
                }
            }

            //Move ogg to EOF folder + rename
            var OggFiles = Directory.GetFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories);

            if (!OggFiles.Any())
            {
                throw new InvalidDataException("Audio files not found.");
            }
            //TODO: read names from bnk and rename.
            var      a0 = new FileInfo(OggFiles[0]);
            FileInfo b0 = null;

            if (OggFiles.Length == 2)
            {
                b0 = new FileInfo(OggFiles[1]);

                if (a0.Length > b0.Length)
                {
                    File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
                    File.Move(b0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg"));
                }
                else
                {
                    File.Move(b0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
                    File.Move(a0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg"));
                }
            }
            else
            {
                File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
            }

            //Move wem to KIT folder + rename
            var WemFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories);

            if (!WemFiles.Any())
            {
                throw new InvalidDataException("Audio files not found.");
            }

            var      a1 = new FileInfo(WemFiles[0]);
            FileInfo b1 = null;

            if (WemFiles.Length == 2)
            {
                b1 = new FileInfo(WemFiles[1]);

                if (a1.Length > b1.Length)
                {
                    File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem"));
                    File.Move(b1.FullName, Path.Combine(kitdir, SongName + "_preview.wem"));
                }
                else
                {
                    File.Move(b1.FullName, Path.Combine(kitdir, SongName + ".wem"));
                    File.Move(a1.FullName, Path.Combine(kitdir, SongName + "_preview.wem"));
                }
            }
            else
            {
                File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem"));
            }

            //Move Appid for correct template generation.
            var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories);

            if (appidFile.Length > 0)
            {
                File.Move(appidFile[0], Path.Combine(kitdir, Path.GetFileName(appidFile[0])));
            }

            //Move toolkit.version
            var toolkitVersion = Directory.GetFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories);

            if (toolkitVersion.Length > 0)
            {
                File.Move(toolkitVersion[0], Path.Combine(kitdir, Path.GetFileName(toolkitVersion[0])));
            }

            //Remove old folder
            DirectoryExtension.SafeDelete(unpackedDir);

            return(outdir);
        }
        private static void UpdateManifest2014(string songDirectory, Platform platform)
        {
            if (platform.version != GameVersion.RS2014)
            {
                return;
            }

            var hsanFiles = Directory.EnumerateFiles(songDirectory, "*.hsan", SearchOption.AllDirectories).ToList();

            if (!hsanFiles.Any())
            {
                throw new DataException("Error: could not find any hsan file");
            }
            if (hsanFiles.Count > 1)
            {
                throw new DataException("Error: there is more than one hsan file");
            }

            var manifestHeader = new ManifestHeader2014 <AttributesHeader2014>(platform);
            var hsanFile       = hsanFiles.First();
            var jsonFiles      = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories).ToList();
            var xmlFiles       = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories).ToList();

            //var songFiles = xmlFiles.Where(x => !x.ToLower().Contains("showlight") && !x.ToLower().Contains("vocal")).ToList();
            //var vocalFiles = xmlFiles.Where(x => x.ToLower().Contains("vocal")).ToList();

            foreach (var xmlFile in xmlFiles)
            {
                var xmlName = Path.GetFileNameWithoutExtension(xmlFile);
                if (xmlName.ToLower().Contains("showlight"))
                {
                    continue;
                }

                var json = jsonFiles.FirstOrDefault(name => Path.GetFileNameWithoutExtension(name) == xmlName);
                if (String.IsNullOrEmpty(json))
                {
                    continue;
                }

                var attr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.First().Value.First().Value;

                if (!xmlName.ToLower().Contains("vocal"))
                {
                    var manifestFunctions = new ManifestFunctions(platform.version);
                    var xmlContent        = Song2014.LoadFromFile(xmlFile);

                    attr.PhraseIterations = new List <Manifest.PhraseIteration>();
                    manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                    attr.Phrases = new List <Manifest.Phrase>();
                    manifestFunctions.GeneratePhraseData(attr, xmlContent);

                    attr.Sections = new List <Manifest.Section>();
                    manifestFunctions.GenerateSectionData(attr, xmlContent);

                    attr.Tuning = new TuningStrings();
                    manifestFunctions.GenerateTuningData(attr, xmlContent);

                    attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);
                }

                // else { // TODO: good place to update vocals }

                // write updated json file
                var attributeDictionary = new Dictionary <string, Attributes2014> {
                    { "Attributes", attr }
                };
                var manifest = new Manifest2014 <Attributes2014>();
                manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                manifest.SaveToFile(json);

                // update manifestHeader (hsan) entry
                var attributeHeaderDictionary = new Dictionary <string, AttributesHeader2014> {
                    { "Attributes", new AttributesHeader2014(attr) }
                };
                if (platform.IsConsole)
                {
                    // One for each arrangements (Xbox360/PS3)
                    manifestHeader = new ManifestHeader2014 <AttributesHeader2014>(platform);
                    manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary);
                }
                else
                {
                    manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary);
                }
            }

            // write updated hsan file
            manifestHeader.SaveToFile(hsanFile);
        }
        /// <summary>
        /// Unpack the specified File, returns unpacked dir.
        /// </summary>
        /// <param name="sourceFileName">Source file path.</param>
        /// <param name="savePath">Save path.</param>
        /// <param name="decodeAudio">If set to <c>true</c> decode audio.</param>
        /// <param name="extractSongXml">If set to <c>true</c> extract song xml from sng.</param>
        /// <param name="overwriteSongXml">If set to <c>true</c> overwrite existing song xml with produced.</param>
        /// <param name="predefinedPlatform">Predefined source platform.</param>
        public static string Unpack(string sourceFileName, string savePath, bool decodeAudio = false, bool extractSongXml = false, bool overwriteSongXml = true, Platform predefinedPlatform = null)
        {
            Platform platform = sourceFileName.GetPlatform();

            if (predefinedPlatform != null && predefinedPlatform.platform != GamePlatform.None && predefinedPlatform.version != GameVersion.None)
            {
                platform = predefinedPlatform;
            }

            var fnameWithoutExt = Path.GetFileNameWithoutExtension(sourceFileName);
            var unpackedDir     = Path.Combine(savePath, String.Format("{0}_{1}", fnameWithoutExt, platform.platform));

            if (Directory.Exists(unpackedDir))
            {
                DirectoryExtension.SafeDelete(unpackedDir);
            }

            var useCryptography = platform.version == GameVersion.RS2012; // Cryptography way is used only for PC in Rocksmith 1

            switch (platform.platform)
            {
            case GamePlatform.Pc:
            case GamePlatform.Mac:
                if (platform.version == GameVersion.RS2014)
                {
                    using (var inputStream = File.OpenRead(sourceFileName))
                        ExtractPSARC(sourceFileName, savePath, inputStream, platform);
                }
                else
                {
                    using (var inputFileStream = File.OpenRead(sourceFileName))
                        using (var inputStream = new MemoryStream())
                        {
                            if (useCryptography)
                            {
                                RijndaelEncryptor.DecryptFile(inputFileStream, inputStream, RijndaelEncryptor.DLCKey);
                            }
                            else
                            {
                                inputFileStream.CopyTo(inputStream);
                            }

                            ExtractPSARC(sourceFileName, savePath, inputStream, platform);
                        }
                }
                break;

            case GamePlatform.XBox360:
                UnpackXBox360Package(sourceFileName, savePath, platform);
                break;

            case GamePlatform.PS3:
                UnpackPS3Package(sourceFileName, savePath, platform);
                break;

            case GamePlatform.None:
                throw new InvalidOperationException("Platform not found :(");
            }

            if (platform.platform == GamePlatform.PS3)
            {
                fnameWithoutExt = fnameWithoutExt.Substring(0, fnameWithoutExt.LastIndexOf("."));
            }

            // DECODE AUDIO
            if (decodeAudio)
            {
                var audioFiles = Directory.EnumerateFiles(unpackedDir, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".ogg") || s.EndsWith(".wem"));
                foreach (var file in audioFiles)
                {
                    var outputAudioFileName = Path.Combine(Path.GetDirectoryName(file), String.Format("{0}_fixed{1}", Path.GetFileNameWithoutExtension(file), ".ogg"));
                    OggFile.Revorb(file, outputAudioFileName, Path.GetDirectoryName(Application.ExecutablePath), Path.GetExtension(file).GetWwiseVersion());
                }
            }

            // EXTRACT XML FROM SNG
            if (extractSongXml && platform.version == GameVersion.RS2014)
            {
                var sngFiles = Directory.EnumerateFiles(unpackedDir, "*.sng", SearchOption.AllDirectories);

                foreach (var sngFile in sngFiles)
                {
                    var xmlOutput = Path.Combine(Path.GetDirectoryName(sngFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(sngFile)));
                    xmlOutput = xmlOutput.Replace(String.Format("bin{0}{1}", Path.DirectorySeparatorChar, platform.GetPathName()[1].ToLower()), "arr");

                    if (File.Exists(xmlOutput) && !overwriteSongXml)
                    {
                        continue;
                    }

                    var arrType = ArrangementType.Guitar;
                    if (Path.GetFileName(xmlOutput).ToLower().Contains("vocal"))
                    {
                        arrType = ArrangementType.Vocal;
                    }

                    Attributes2014 att = null;
                    if (arrType != ArrangementType.Vocal)
                    {
                        var jsonFiles = Directory.EnumerateFiles(unpackedDir, String.Format("{0}.json", Path.GetFileNameWithoutExtension(sngFile)), SearchOption.AllDirectories).FirstOrDefault();
                        if (jsonFiles.Any() && !String.IsNullOrEmpty(jsonFiles))
                        {
                            att = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles).Entries.ToArray()[0].Value.ToArray()[0].Value;
                        }
                    }

                    var sngContent = Sng2014File.LoadFromFile(sngFile, platform);
                    using (var outputStream = new FileStream(xmlOutput, FileMode.Create, FileAccess.ReadWrite))
                    {
                        dynamic xmlContent = null;

                        if (arrType == ArrangementType.Vocal)
                        {
                            xmlContent = new Vocals(sngContent);
                        }
                        else
                        {
                            xmlContent = new Song2014(sngContent, att);
                        }

                        xmlContent.Serialize(outputStream);
                    }
                }
            }

            return(unpackedDir);
        }
        static int Main(string[] args)
        {
            var arguments = DefaultArguments();
            var options   = GetOptions(arguments);

            try {
                options.Parse(args);

                if (arguments.ShowHelp)
                {
                    options.WriteOptionDescriptions(Console.Out);
                    return(0);
                }

                if (!arguments.Pack && !arguments.Unpack && !arguments.Sng2Xml && !arguments.Xml2Sng)
                {
                    ShowHelpfulError("Must especify a primary command as 'pack', 'unpack', 'sng2xml' or 'xml2sng'.");
                    return(1);
                }

                if (arguments.Input == null && arguments.Input.Length <= 0)
                {
                    ShowHelpfulError("Must specify at least one input file.");
                    return(1);
                }

                if (arguments.Sng2Xml && arguments.Manifest == null && arguments.Manifest.Length <= 0)
                {
                    Console.WriteLine("No manifest file was entered. The song xml file will be generated without song informations like song title, album, artist, tone names, etc.");
                }

                var srcFiles = new List <string>();
                foreach (var name in arguments.Input)
                {
                    if (name.IsDirectory())
                    {
                        srcFiles.AddRange(Directory.EnumerateFiles(Path.GetFullPath(name), "*.sng", SearchOption.AllDirectories));
                    }

                    if (File.Exists(name))
                    {
                        srcFiles.Add(name);
                    }
                }

                var errorCount = 0;
                var indexCount = 0;
                foreach (string inputFile in srcFiles)
                {
                    if (!File.Exists(inputFile))
                    {
                        Console.WriteLine(String.Format("File '{0}' doesn't exists.", inputFile));
                        continue;
                    }

                    if (arguments.Unpack || arguments.Sng2Xml)
                    {
                        if (Path.GetExtension(inputFile) != ".sng")
                        {
                            Console.WriteLine(String.Format("File '{0}' is not support. \nOnly *.sng are supported on this command.", inputFile));
                            continue;
                        }
                    }

                    if (arguments.Pack || arguments.Unpack)
                    {
                        var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}_{1}.sng", Path.GetFileNameWithoutExtension(inputFile), (arguments.Unpack) ? "decrypted" : "encrypted"));

                        using (FileStream inputStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
                            using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) {
                                if (arguments.Pack)
                                {
                                    Sng2014File.PackSng(inputStream, outputStream, new Platform(arguments.Platform, GameVersion.RS2014));
                                }
                                else if (arguments.Unpack)
                                {
                                    Sng2014File.UnpackSng(inputStream, outputStream, new Platform(arguments.Platform, GameVersion.RS2014));
                                }
                            }
                    }
                    else if (arguments.Sng2Xml)
                    {
                        Attributes2014 att = null;
                        if (arguments.ArrangementType != ArrangementType.Vocal && arguments.Manifest != null && arguments.Manifest.Length > indexCount)
                        {
                            att = Manifest2014 <Attributes2014> .LoadFromFile(arguments.Manifest[indexCount]).Entries.ToArray()[0].Value.ToArray()[0].Value;
                        }

                        var sng = Sng2014File.LoadFromFile(inputFile, new Platform(arguments.Platform, GameVersion.RS2014));

                        var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}.xml", Path.GetFileNameWithoutExtension(inputFile)));
                        using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite))
                        {
                            dynamic xml = null;

                            if (arguments.ArrangementType == ArrangementType.Vocal)
                            {
                                xml = new Vocals(sng);
                            }
                            else
                            {
                                xml = new Song2014(sng, att ?? null);
                            }

                            xml.Serialize(outputStream);
                        }
                    }
                    else if (arguments.Xml2Sng)
                    {
                        var outputFile = Path.Combine(Path.GetDirectoryName(inputFile), String.Format("{0}.sng", Path.GetFileNameWithoutExtension(inputFile)));

                        using (FileStream outputStream = new FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite)) {
                            Sng2014File sng = Sng2014File.ConvertXML(inputFile, arguments.ArrangementType);
                            sng.WriteSng(outputStream, new Platform(arguments.Platform, GameVersion.RS2014));
                        }
                    }
                }

                if (errorCount == 0)
                {
                    Console.WriteLine("Process successfully completed!");
                }
                else if (errorCount > 0 && errorCount < srcFiles.Count)
                {
                    Console.WriteLine("Process completed with errors!");
                }
                else
                {
                    Console.WriteLine("An error occurred!");
                }
            } catch (OptionException ex) {
                ShowHelpfulError(ex.Message);
                return(1);
            }

            return(0);
        }
Esempio n. 16
0
        public static string DoLikeProject(string unpackedDir)
        {
            //Get name for new folder name
            string outdir    = "";
            string EOF       = "EOF";
            string KIT       = "Toolkit";
            string SongName  = "SongName";
            var    jsonFiles = Directory.GetFiles(unpackedDir, "*.json", SearchOption.AllDirectories);
            var    attr      = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value;

            //Create dir sruct
            SongName = attr.FullName.Split('_')[0];
            outdir   = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", attr.ArtistNameSort.GetValidName(false), attr.SongNameSort.GetValidName(false)));
            if (Directory.Exists(outdir))
            {
                outdir += "_" + DateTime.Now.ToString("yyyy-MM-dd");
            }

            Directory.CreateDirectory(outdir);
            Directory.CreateDirectory(Path.Combine(outdir, EOF));
            Directory.CreateDirectory(Path.Combine(outdir, KIT));

            foreach (var json in jsonFiles)
            {
                var atr = Manifest2014 <Attributes2014> .LoadFromFile(json).Entries.ToArray()[0].Value.ToArray()[0].Value;

                var Name    = atr.SongXml.Split(':')[3];
                var xmlFile = Directory.GetFiles(unpackedDir, Name + ".xml", SearchOption.AllDirectories)[0];

                //Move all pair JSON\XML
                File.Move(json, Path.Combine(outdir, KIT, Name + ".json"));
                File.Move(xmlFile, Path.Combine(outdir, EOF, Name + ".xml"));
            }

            //Move art_256.dds to KIT folder
            var ArtFile = Directory.GetFiles(unpackedDir, "*_256.dds", SearchOption.AllDirectories);

            if (ArtFile.Length > 0)
            {
                File.Move(ArtFile[0], Path.Combine(outdir, KIT, Path.GetFileName(ArtFile[0])));
            }

            //Move ogg to EOF folder + rename
            var OggFiles = Directory.GetFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories);

            if (OggFiles.Count() <= 0)
            {
                throw new InvalidDataException("Audio files not found.");
            }

            var      a0 = new FileInfo(OggFiles[0]);
            FileInfo b0 = null;

            if (OggFiles.Count() == 2)
            {
                b0 = new FileInfo(OggFiles[1]);

                if (a0.Length > b0.Length)
                {
                    File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg"));
                    File.Move(b0.FullName, Path.Combine(outdir, EOF, SongName + "_preview.ogg"));
                }
                else
                {
                    File.Move(b0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg"));
                    File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + "_preview.ogg"));
                }
            }
            else
            {
                File.Move(a0.FullName, Path.Combine(outdir, EOF, SongName + ".ogg"));
            }

            //Move wem to KIT folder + rename
            var WemFiles = Directory.GetFiles(unpackedDir, "*.wem", SearchOption.AllDirectories);

            if (WemFiles.Count() <= 0)
            {
                throw new InvalidDataException("Audio files not found.");
            }

            var      a1 = new FileInfo(WemFiles[0]);
            FileInfo b1 = null;

            if (WemFiles.Count() == 2)
            {
                b1 = new FileInfo(WemFiles[1]);

                if (a1.Length > b1.Length)
                {
                    File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + ".wem"));
                    File.Move(b1.FullName, Path.Combine(outdir, KIT, SongName + "_preview.wem"));
                }
                else
                {
                    File.Move(b1.FullName, Path.Combine(outdir, KIT, SongName + ".wem"));
                    File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + "_preview.wem"));
                }
            }
            else
            {
                File.Move(a1.FullName, Path.Combine(outdir, KIT, SongName + ".wem"));
            }

            //Move Appid for correct template generation.
            var appidFile = Directory.GetFiles(unpackedDir, "*.appid", SearchOption.AllDirectories);

            if (appidFile.Length > 0)
            {
                File.Move(appidFile[0], Path.Combine(outdir, KIT, Path.GetFileName(appidFile[0])));
            }

            //Remove old folder
            DirectoryExtension.SafeDelete(unpackedDir);

            return(outdir);
        }
Esempio n. 17
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);
        }
Esempio n. 18
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);
        }
        private static void GenerateRS2014SongPsarc(Stream output, DLCPackageData info, Platform platform, int pnum = -1)
        {
            // TODO: Benchmark processes and optimize speed
            dlcName = info.Name.ToLower();
            packPsarc = new PSARC.PSARC();

            // Stream objects
            Stream soundStream = null,
                   soundPreviewStream = null,
                   rsenumerableRootStream = null,
                   rsenumerableSongStream = null;

            try
            {
                // ALBUM ART
                var ddsfiles = info.ArtFiles;

                if (ddsfiles == null)
                {
                    string albumArtPath;
                    if (File.Exists(info.AlbumArtPath))
                    {
                        albumArtPath = info.AlbumArtPath;
                    }
                    else
                    {
                        using (var albumArtStream = new MemoryStream(Resources.albumart2014_256))
                        {
                            albumArtPath = GeneralExtensions.GetTempFileName(".dds");
                            albumArtStream.WriteFile(albumArtPath);
                            TMPFILES_ART.Add(albumArtPath);
                        }
                    }

                    ddsfiles = new List<DDSConvertedFile>();
                    ddsfiles.Add(new DDSConvertedFile() { sizeX = 64, sizeY = 64, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                    ddsfiles.Add(new DDSConvertedFile() { sizeX = 128, sizeY = 128, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });
                    ddsfiles.Add(new DDSConvertedFile() { sizeX = 256, sizeY = 256, sourceFile = albumArtPath, destinationFile = GeneralExtensions.GetTempFileName(".dds") });

                    // Convert to DDS
                    ToDDS(ddsfiles);

                    // Save for reuse
                    info.ArtFiles = ddsfiles;
                }

                foreach (var dds in info.ArtFiles)
                {
                    packPsarc.AddEntry(String.Format("gfxassets/album_art/album_{0}_{1}.dds", dlcName, dds.sizeX), new FileStream(dds.destinationFile, FileMode.Open, FileAccess.Read, FileShare.Read));
                    TMPFILES_ART.Add(dds.destinationFile);
                }

                // Lyric Art Texture
                if (File.Exists(info.LyricArtPath))
                    packPsarc.AddEntry(String.Format("assets/ui/lyrics/{0}/lyrics_{0}.dds", dlcName), new FileStream(info.LyricArtPath, FileMode.Open, FileAccess.Read, FileShare.Read));

                // AUDIO
                var audioFile = info.OggPath;
                if (File.Exists(audioFile))
                    if (platform.IsConsole != audioFile.GetAudioPlatform().IsConsole)
                        soundStream = OggFile.ConvertAudioPlatform(audioFile);
                    else
                        soundStream = File.OpenRead(audioFile);
                else
                    throw new InvalidOperationException(String.Format("Audio file '{0}' not found.", audioFile));

                // AUDIO PREVIEW
                var previewAudioFile = info.OggPreviewPath;
                if (File.Exists(previewAudioFile))
                    if (platform.IsConsole != previewAudioFile.GetAudioPlatform().IsConsole)
                        soundPreviewStream = OggFile.ConvertAudioPlatform(previewAudioFile);
                    else
                        soundPreviewStream = File.OpenRead(previewAudioFile);
                else
                    soundPreviewStream = soundStream;

                // FLAT MODEL
                rsenumerableRootStream = new MemoryStream(Resources.rsenumerable_root);
                packPsarc.AddEntry("flatmodels/rs/rsenumerable_root.flat", rsenumerableRootStream);
                rsenumerableSongStream = new MemoryStream(Resources.rsenumerable_song);
                packPsarc.AddEntry("flatmodels/rs/rsenumerable_song.flat", rsenumerableSongStream);

                using (var toolkitVersionStream = new MemoryStream())
                using (var appIdStream = new MemoryStream())
                using (var packageListStream = new MemoryStream())
                using (var soundbankStream = new MemoryStream())
                using (var soundbankPreviewStream = new MemoryStream())
                using (var aggregateGraphStream = new MemoryStream())
                using (var manifestHeaderHSANStream = new MemoryStream())
                using (var manifestHeaderHSONStreamList = new DisposableCollection<Stream>())
                using (var manifestStreamList = new DisposableCollection<Stream>())
                using (var arrangementStream = new DisposableCollection<Stream>())
                using (var showlightStream = new MemoryStream())
                using (var xblockStream = new MemoryStream())
                {
                    // TOOLKIT VERSION
                    var stopHere = info;
                    GenerateToolkitVersion(toolkitVersionStream, info.ToolkitInfo.PackageAuthor, info.ToolkitInfo.PackageVersion, info.ToolkitInfo.PackageComment);
                    packPsarc.AddEntry("toolkit.version", toolkitVersionStream);

                    // APP ID
                    if (!platform.IsConsole)
                    {
                        GenerateAppId(appIdStream, info.AppId, platform);
                        packPsarc.AddEntry("appid.appid", appIdStream);
                    }

                    if (platform.platform == GamePlatform.XBox360)
                    {
                        var packageListWriter = new StreamWriter(packageListStream);
                        packageListWriter.Write(dlcName);
                        packageListWriter.Flush();
                        packageListStream.Seek(0, SeekOrigin.Begin);
                        packageListStream.WriteTmpFile("PackageList.txt", platform);
                    }

                    // SOUNDBANK
                    var soundbankFileName = String.Format("song_{0}", dlcName);
                    var audioFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name, soundStream, soundbankStream, info.Volume, platform);
                    packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankFileName), soundbankStream);
                    packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioFileNameId), soundStream);

                    // SOUNDBANK PREVIEW
                    var soundbankPreviewFileName = String.Format("song_{0}_preview", dlcName);
                    dynamic audioPreviewFileNameId;
                    var previewVolume = info.PreviewVolume ?? info.Volume;
                    audioPreviewFileNameId = SoundBankGenerator2014.GenerateSoundBank(info.Name + "_Preview", soundPreviewStream, soundbankPreviewStream, previewVolume, platform, true, !(File.Exists(previewAudioFile)));
                    packPsarc.AddEntry(String.Format("audio/{0}/{1}.bnk", platform.GetPathName()[0].ToLower(), soundbankPreviewFileName), soundbankPreviewStream);
                    if (!soundPreviewStream.Equals(soundStream)) packPsarc.AddEntry(String.Format("audio/{0}/{1}.wem", platform.GetPathName()[0].ToLower(), audioPreviewFileNameId), soundPreviewStream);

                    // AGGREGATE GRAPH
                    var aggregateGraphFileName = String.Format("{0}_aggregategraph.nt", dlcName);
                    var aggregateGraph = new AggregateGraph2014.AggregateGraph2014(info, platform);
                    aggregateGraph.Serialize(aggregateGraphStream);
                    aggregateGraphStream.Flush();
                    aggregateGraphStream.Seek(0, SeekOrigin.Begin);
                    packPsarc.AddEntry(aggregateGraphFileName, aggregateGraphStream);

                    var manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
                    var songPartition = new SongPartition();
                    var songPartitionCount = new SongPartition();

                    foreach (var arrangement in info.Arrangements)
                    {
                        if (arrangement.ArrangementType == ArrangementType.ShowLight)
                            continue;

                        var arrangementFileName = songPartition.GetArrangementFileName(arrangement.Name, arrangement.ArrangementType).ToLower();

                        // GAME SONG (SNG)
                        UpdateToneDescriptors(info);
                        GenerateSNG(arrangement, platform);
                        var sngSongFile = File.OpenRead(arrangement.SongFile.File);
                        arrangementStream.Add(sngSongFile);
                        packPsarc.AddEntry(String.Format("songs/bin/{0}/{1}_{2}.sng", platform.GetPathName()[1].ToLower(), dlcName, arrangementFileName), sngSongFile);

                        // XML SONG
                        var xmlSongFile = File.OpenRead(arrangement.SongXml.File);
                        arrangementStream.Add(xmlSongFile);
                        packPsarc.AddEntry(String.Format("songs/arr/{0}_{1}.xml", dlcName, arrangementFileName), xmlSongFile);

                        // MANIFEST
                        var manifest = new Manifest2014<Attributes2014>();
                        var attribute = new Attributes2014(arrangementFileName, arrangement, info, platform);
                        if (arrangement.ArrangementType == ArrangementType.Bass || arrangement.ArrangementType == ArrangementType.Guitar)
                        {
                            // TODO: monitor this new code for bugs
                            // represent is set to "1" by default, if there is a bonus then set represent to "0"
                            attribute.Representative = arrangement.BonusArr ? 0 : 1;
                            attribute.ArrangementProperties.Represent = arrangement.BonusArr ? 0 : 1;

                            attribute.SongPartition = songPartitionCount.GetSongPartition(arrangement.Name, arrangement.ArrangementType);
                            if (attribute.SongPartition > 1 && !arrangement.BonusArr)
                            {
                                // for alternate arrangement then both represent and bonus are set to "0"
                                attribute.Representative = 0;
                                attribute.ArrangementProperties.Represent = 0;
                            }
                        }

                        var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attribute } };
                        manifest.Entries.Add(attribute.PersistentID, attributeDictionary);
                        var manifestStream = new MemoryStream();
                        manifestStreamList.Add(manifestStream);
                        manifest.Serialize(manifestStream);
                        manifestStream.Seek(0, SeekOrigin.Begin);

                        const string jsonPathPC = "manifests/songs_dlc_{0}/{0}_{1}.json";
                        const string jsonPathConsole = "manifests/songs_dlc/{0}_{1}.json";
                        packPsarc.AddEntry(String.Format((platform.IsConsole ? jsonPathConsole : jsonPathPC), dlcName, arrangementFileName), manifestStream);

                        // MANIFEST HEADER
                        var attributeHeaderDictionary = new Dictionary<string, AttributesHeader2014> { { "Attributes", new AttributesHeader2014(attribute) } };

                        if (platform.IsConsole)
                        {
                            // One for each arrangements (Xbox360/PS3)
                            manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
                            manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary);
                            var manifestHeaderStream = new MemoryStream();
                            manifestHeaderHSONStreamList.Add(manifestHeaderStream);
                            manifestHeader.Serialize(manifestHeaderStream);
                            manifestStream.Seek(0, SeekOrigin.Begin);
                            packPsarc.AddEntry(String.Format("manifests/songs_dlc/{0}_{1}.hson", dlcName, arrangementFileName), manifestHeaderStream);
                        }
                        else
                        {
                            // One for all arrangements (PC/Mac)
                            manifestHeader.Entries.Add(attribute.PersistentID, attributeHeaderDictionary);
                        }
                    }

                    if (!platform.IsConsole)
                    {
                        manifestHeader.Serialize(manifestHeaderHSANStream);
                        manifestHeaderHSANStream.Seek(0, SeekOrigin.Begin);
                        packPsarc.AddEntry(String.Format("manifests/songs_dlc_{0}/songs_dlc_{0}.hsan", dlcName), manifestHeaderHSANStream);
                    }

                    // XML SHOWLIGHTS
                    var shlArr = info.Arrangements.FirstOrDefault(ar => ar.ArrangementType == ArrangementType.ShowLight);
                    if (shlArr != null && shlArr.SongXml.File != null)
                        using (var fs = File.OpenRead(shlArr.SongXml.File))
                            fs.CopyTo(showlightStream);
                    else
                    {
                        var showlight = new Showlights(info);
                        showlight.Serialize(showlightStream);
                        string shlFilePath = Path.Combine(Path.GetDirectoryName(info.Arrangements[0].SongXml.File), String.Format("{0}_showlights.xml", "cst"));
                        using (FileStream file = new FileStream(shlFilePath, FileMode.Create, FileAccess.Write))
                            showlightStream.WriteTo(file);
                    }

                    if (showlightStream.CanRead && showlightStream.Length > 0)
                        packPsarc.AddEntry(String.Format("songs/arr/{0}_showlights.xml", dlcName), showlightStream);

                    // XBLOCK
                    var game = GameXblock<Entity2014>.Generate2014(info, platform);
                    game.SerializeXml(xblockStream);
                    xblockStream.Flush();
                    xblockStream.Seek(0, SeekOrigin.Begin);
                    packPsarc.AddEntry(String.Format("gamexblocks/nsongs/{0}.xblock", dlcName), xblockStream);

                    // WRITE PACKAGE
                    packPsarc.Write(output, !platform.IsConsole);
                    output.WriteTmpFile(String.Format("{0}.psarc", dlcName), platform);
                }
            }
            finally
            {
                // Dispose all objects
                if (soundStream != null)
                    soundStream.Dispose();
                if (soundPreviewStream != null)
                    soundPreviewStream.Dispose();
                if (rsenumerableRootStream != null)
                    rsenumerableRootStream.Dispose();
                if (rsenumerableSongStream != null)
                    rsenumerableSongStream.Dispose();
                if (pnum <= 1)
                    DeleteTmpFiles(TMPFILES_ART);
                DeleteTmpFiles(TMPFILES_SNG);
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Transforms unpacked Song into project-like folder structure.
        /// </summary>
        /// <returns>Output folder path.</returns>
        /// <param name="unpackedDir">Unpacked dir.</param>
        public static string DoLikeProject(string unpackedDir)
        {
            const string EOF         = "EOF";
            const string KIT         = "Toolkit";
            string       SongName    = "SongName";
            string       songVersion = "v0";

            // Get name for a new folder
            var jsonFiles = Directory.EnumerateFiles(unpackedDir, "*.json", SearchOption.AllDirectories).ToArray();
            var attr      = Manifest2014 <Attributes2014> .LoadFromFile(jsonFiles[0]).Entries.ToArray()[0].Value.ToArray()[0].Value;

            var fileNameParts = Path.GetFileNameWithoutExtension(unpackedDir).Split('_');

            if (fileNameParts.Length > 3)
            {
                songVersion = fileNameParts[2];
            }
            SongName = attr.FullName.Split('_')[0];

            //Create dir struct
            var outdir = Path.Combine(Path.GetDirectoryName(unpackedDir), String.Format("{0}_{1}", SongName, songVersion).Replace(" ", "-"));
            var eofdir = Path.Combine(outdir, EOF);
            var kitdir = Path.Combine(outdir, KIT);

            attr = null; //dispose

            // Don't work in same dir
            if (Directory.Exists(outdir))
            {
                if (outdir == unpackedDir)
                {
                    return(unpackedDir);
                }
                DirectoryExtension.SafeDelete(outdir);
            }

            Directory.CreateDirectory(outdir);
            Directory.CreateDirectory(eofdir);
            Directory.CreateDirectory(kitdir);

            var xmlFiles = Directory.EnumerateFiles(unpackedDir, "*.xml", SearchOption.AllDirectories).ToArray();
            var sngFiles = Directory.EnumerateFiles(unpackedDir, "*vocals.sng", SearchOption.AllDirectories).ToArray();

            foreach (var json in jsonFiles)
            {
                var name    = Path.GetFileNameWithoutExtension(json);
                var xmlFile = xmlFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == name);
                var sngFile = sngFiles.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == name);

                //Move all pair JSON\XML
                File.Move(json, Path.Combine(kitdir, name + ".json"));
                File.Move(xmlFile, Path.Combine(eofdir, name + ".xml"));
                if (name.EndsWith("vocals", StringComparison.Ordinal))
                {
                    File.Move(sngFile, Path.Combine(kitdir, name + ".sng"));
                }
            }

            // move showlights.xml
            var showlightPath = Directory.EnumerateFiles(unpackedDir, "*_showlights.xml", SearchOption.AllDirectories).ToArray();

            if (showlightPath.Any())
            {
                File.Move(showlightPath[0], Path.Combine(eofdir, Path.GetFileName(showlightPath[0])));
            }

            //Move all art_size.dds to KIT folder
            var artFiles = Directory.EnumerateFiles(unpackedDir, "album_*_*.dds", SearchOption.AllDirectories).ToArray();

            if (artFiles.Any())
            {
                foreach (var art in artFiles)
                {
                    File.Move(art, Path.Combine(kitdir, Path.GetFileName(art)));
                }
            }
            var lyricArt = Directory.EnumerateFiles(unpackedDir, "lyrics_*.dds", SearchOption.AllDirectories).ToArray();

            if (lyricArt.Any())
            {
                foreach (var art in lyricArt)
                {
                    File.Move(art, Path.Combine(kitdir, Path.GetFileName(art)));
                }
            }

            //Move ogg to EOF folder + rename
            var oggFiles = Directory.EnumerateFiles(unpackedDir, "*_fixed.ogg", SearchOption.AllDirectories).ToArray();

            if (!oggFiles.Any())
            {
                throw new InvalidDataException("Audio files not found.");
            }
            // TODO: read names from bnk and rename.
            // TODO: FIX THIS ... not valid for short jingle/riff CDLC < 30 seconds
            // because the preview 30 seconds is larger than actual song
            // need to base preview decision on duration not size
            var a0 = new FileInfo(oggFiles[0]);

            if (oggFiles.Count() == 2)
            {
                var b0 = new FileInfo(oggFiles[1]);

                if (a0.Length > b0.Length)
                {
                    File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
                    File.Move(b0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg"));
                }
                else
                {
                    File.Move(b0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
                    File.Move(a0.FullName, Path.Combine(eofdir, SongName + "_preview.ogg"));
                }
            }
            else
            {
                File.Move(a0.FullName, Path.Combine(eofdir, SongName + ".ogg"));
            }

            //Move wem to KIT folder + rename
            var wemFiles = Directory.EnumerateFiles(unpackedDir, "*.wem", SearchOption.AllDirectories).ToArray();

            if (!wemFiles.Any())
            {
                throw new InvalidDataException("Audio files not found.");
            }

            // TODO: FIX THIS ... not valid for short jingle/riff CDLC < 30 seconds
            // because the preview 30 seconds is larger than actual song
            // need to base preview decision on duration not size
            var a1 = new FileInfo(wemFiles[0]);

            if (wemFiles.Count() == 2)
            {
                var b1 = new FileInfo(wemFiles[1]);

                if (a1.Length > b1.Length)
                {
                    File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem"));
                    File.Move(b1.FullName, Path.Combine(kitdir, SongName + "_preview.wem"));
                }
                else
                {
                    File.Move(b1.FullName, Path.Combine(kitdir, SongName + ".wem"));
                    File.Move(a1.FullName, Path.Combine(kitdir, SongName + "_preview.wem"));
                }
            }
            else
            {
                File.Move(a1.FullName, Path.Combine(kitdir, SongName + ".wem"));
            }

            //Move Appid for correct template generation.
            var appidFile = Directory.EnumerateFiles(unpackedDir, "*.appid", SearchOption.AllDirectories).FirstOrDefault();

            if (appidFile != null)
            {
                File.Move(appidFile, Path.Combine(kitdir, Path.GetFileName(appidFile)));
            }

            //Move toolkit.version
            var toolkitVersion = Directory.EnumerateFiles(unpackedDir, "toolkit.version", SearchOption.AllDirectories).FirstOrDefault();

            if (toolkitVersion != null)
            {
                File.Move(toolkitVersion, Path.Combine(kitdir, Path.GetFileName(toolkitVersion)));
            }

            //Remove old folder
            DirectoryExtension.SafeDelete(unpackedDir);

            return(outdir);
        }
Esempio n. 21
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);
        }
        private static void UpdateManifest2014(string songDirectory, Platform platform)
        {
            // UPDATE MANIFEST (RS2014)
            if (platform.version == GameVersion.RS2014)
            {
                var xmlFiles = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories);
                var jsonFiles = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories);
                foreach (var xml in xmlFiles)
                {
                    var xmlName = Path.GetFileNameWithoutExtension(xml);
                    if (xmlName.ToUpperInvariant().Contains("SHOWLIGHT"))
                        continue;
                    if (xmlName.ToUpperInvariant().Contains("VOCAL"))
                        continue;//TODO: Re-generate vocals manifest.

                    string json = jsonFiles.FirstOrDefault(name => Path.GetFileNameWithoutExtension(name) == xmlName);
                    if (!String.IsNullOrEmpty(json))
                    {
                        var xmlContent = Song2014.LoadFromFile(xml);
                        var manifest = new Manifest2014<Attributes2014>();
                        var attr = Manifest2014<Attributes2014>.LoadFromFile(json).Entries.First().Value.First().Value;

                        var manifestFunctions = new ManifestFunctions(platform.version);

                        attr.PhraseIterations = new List<Manifest.PhraseIteration>();
                        manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                        attr.Phrases = new List<Manifest.Phrase>();
                        manifestFunctions.GeneratePhraseData(attr, xmlContent);

                        attr.Sections = new List<Manifest.Section>();
                        manifestFunctions.GenerateSectionData(attr, xmlContent);

                        attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);

                        var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attr } };
                        manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                        manifest.SaveToFile(json);
                    }
                }
            }
        }
        private static void UpdateManifest2014(string songDirectory, Platform platform)
        {
            if (platform.version != GameVersion.RS2014)
                return;

            var hsanFiles = Directory.EnumerateFiles(songDirectory, "*.hsan", SearchOption.AllDirectories).ToList();
            if (!hsanFiles.Any())
                throw new DataException("Error: could not find any hsan file");
            if (hsanFiles.Count > 1)
                throw new DataException("Error: there is more than one hsan file");

            var manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
            var hsanFile = hsanFiles.First();
            var jsonFiles = Directory.EnumerateFiles(songDirectory, "*.json", SearchOption.AllDirectories).ToList();
            var xmlFiles = Directory.EnumerateFiles(songDirectory, "*.xml", SearchOption.AllDirectories).ToList();
            //var songFiles = xmlFiles.Where(x => !x.ToLower().Contains("showlight") && !x.ToLower().Contains("vocal")).ToList();
            //var vocalFiles = xmlFiles.Where(x => x.ToLower().Contains("vocal")).ToList();

            foreach (var xmlFile in xmlFiles)
            {
                var xmlName = Path.GetFileNameWithoutExtension(xmlFile);
                if (xmlName.ToLower().Contains("showlight"))
                    continue;

                var json = jsonFiles.FirstOrDefault(name => Path.GetFileNameWithoutExtension(name) == xmlName);
                if (String.IsNullOrEmpty(json))
                    continue;

                var attr = Manifest2014<Attributes2014>.LoadFromFile(json).Entries.First().Value.First().Value;

                if (!xmlName.ToLower().Contains("vocal"))
                {
                    var manifestFunctions = new ManifestFunctions(platform.version);
                    var xmlContent = Song2014.LoadFromFile(xmlFile);

                    attr.PhraseIterations = new List<Manifest.PhraseIteration>();
                    manifestFunctions.GeneratePhraseIterationsData(attr, xmlContent, platform.version);

                    attr.Phrases = new List<Manifest.Phrase>();
                    manifestFunctions.GeneratePhraseData(attr, xmlContent);

                    attr.Sections = new List<Manifest.Section>();
                    manifestFunctions.GenerateSectionData(attr, xmlContent);

                    attr.Tuning = new TuningStrings();
                    manifestFunctions.GenerateTuningData(attr, xmlContent);

                    attr.MaxPhraseDifficulty = manifestFunctions.GetMaxDifficulty(xmlContent);
                }

                // else { // TODO: good place to update vocals }

                // write updated json file
                var attributeDictionary = new Dictionary<string, Attributes2014> { { "Attributes", attr } };
                var manifest = new Manifest2014<Attributes2014>();
                manifest.Entries.Add(attr.PersistentID, attributeDictionary);
                manifest.SaveToFile(json);

                // update manifestHeader (hsan) entry
                var attributeHeaderDictionary = new Dictionary<string, AttributesHeader2014> { { "Attributes", new AttributesHeader2014(attr) } };
                if (platform.IsConsole)
                {
                    // One for each arrangements (Xbox360/PS3)
                    manifestHeader = new ManifestHeader2014<AttributesHeader2014>(platform);
                    manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary);
                }
                else
                    manifestHeader.Entries.Add(attr.PersistentID, attributeHeaderDictionary);
            }

            // write updated hsan file
            manifestHeader.SaveToFile(hsanFile);
        }