Ejemplo n.º 1
0
        /// <summary>
        /// Reads psarc file from filepath and populates details with information
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="details"></param>
        internal static Dictionary <string, SongDetails> ReadPSARCHeaderData(FileInfo fileInfo)
        {
            //Wait for the file to exist
            WaitForFile(fileInfo);

            if (!fileInfo.Exists)
            {
                Logger.LogError("Warning! Psarc file {0} does not exist!", fileInfo.FullName);
                return(null);
            }

            var sw = new Stopwatch();

            sw.Start();

            string fileHash = GetFileHash(fileInfo);

            var detailsDict = new Dictionary <string, SongDetails>();

            using (PsarcFile loader = new PsarcFile(fileInfo))
            {
                //Extract toolkit info
                var tkInfo = loader.ExtractToolkitInfo();

                List <SongArrangement> manifests;

                try
                {
                    manifests = loader.ExtractArrangementManifests();
                }
                catch (Exception e)
                {
                    Logger.LogError("Warning! Could not parse psarc file {0}: {1}", fileInfo.Name, e.Message);
                    return(null);
                }

                //Extract all arrangements
                foreach (var v in manifests)
                {
                    if (v == null)
                    {
                        Logger.LogError("Unable to process JSON manifest for {0}", fileInfo.Name);
                        continue;
                    }

                    var arrangement    = v.Attributes;
                    var arrangement_id = arrangement.PersistentID;

                    var             arrangementSng  = loader.InflateEntry <SngAsset>(a => a.Path.Equals($"songs/bin/generic/{arrangement.SongXml.Substring(20)}.sng"));
                    ArrangementData arrangementData = new ArrangementData(arrangementSng);

                    if (arrangement.Phrases != null)
                    {
                        if (!detailsDict.ContainsKey(arrangement.SongKey))
                        {
                            detailsDict[arrangement.SongKey] = new SongDetails();
                        }

                        SongDetails details = detailsDict[arrangement.SongKey];

                        if (details.albumArt == null)
                        {
                            try
                            {
                                details.albumArt = loader.ExtractAlbumArt(arrangement).Bitmap;
                            }
                            catch (Exception e)
                            {
                                Logger.LogError("Warning: couldn't extract album art for {0}", arrangement.SongName);
#if DEBUG
                                Logger.LogException(e);
#endif

                                details.albumArt = new Bitmap(1, 1);
                            }
                        }

                        //Get a list of all sections
                        var sections = new List <ArrangementDetails.SectionDetails>();
                        Dictionary <string, int> sectionCounts = new Dictionary <string, int>();

                        foreach (var sect in arrangement.Sections)
                        {
                            if (!sectionCounts.ContainsKey(sect.Name))
                            {
                                sectionCounts[sect.Name] = 1;
                            }

                            var sectionDetails = new ArrangementDetails.SectionDetails
                            {
                                name      = $"{sect.Name} {sectionCounts[sect.Name]}",
                                startTime = sect.StartTime,
                                endTime   = sect.EndTime
                            };

                            sections.Add(sectionDetails);

                            sectionCounts[sect.Name]++;
                        }


                        //Get a list of all phraseIterations
                        var phraseIterations = new List <ArrangementDetails.PhraseIterationDetails>();
                        Dictionary <string, int> phraseIterationCounts = new Dictionary <string, int>();

                        foreach (var phrI in arrangement.PhraseIterations)
                        {
                            if (!phraseIterationCounts.ContainsKey(phrI.Name))
                            {
                                phraseIterationCounts[phrI.Name] = 1;
                            }

                            var phraseIterationDetails = new ArrangementDetails.PhraseIterationDetails
                            {
                                name          = $"{phrI.Name} {phraseIterationCounts[phrI.Name]}",
                                phraseId      = phrI.PhraseIndex,
                                maxDifficulty = phrI.MaxDifficulty,
                                startTime     = phrI.StartTime,
                                endTime       = phrI.EndTime
                            };

                            phraseIterations.Add(phraseIterationDetails);

                            phraseIterationCounts[phrI.Name]++;
                        }

                        //Build arrangement details
                        var arrangementDetails = new ArrangementDetails
                        {
                            name                   = arrangement.ArrangementName,
                            arrangementID          = arrangement_id,
                            sections               = sections,
                            phraseIterations       = phraseIterations,
                            data                   = arrangementData,
                            isBonusArrangement     = (arrangement.ArrangementProperties.BonusArr == 1),
                            isAlternateArrangement = (arrangement.ArrangementProperties.Represent == 0)
                        };

                        //Determine path type
                        if (arrangement.ArrangementProperties.PathLead == 1)
                        {
                            arrangementDetails.type = "Lead";
                        }
                        else if (arrangement.ArrangementProperties.PathRhythm == 1)
                        {
                            arrangementDetails.type = "Rhythm";
                        }
                        else if (arrangement.ArrangementProperties.PathBass == 1)
                        {
                            arrangementDetails.type = "Bass";
                        }

                        arrangementDetails.tuning = new ArrangementTuning(arrangement.Tuning, (int)arrangement.CentOffset, (int)arrangement.CapoFret);


                        //file hash
                        details.psarcFileHash = fileHash;

                        //Get general song information
                        details.songID     = arrangement.SongKey;
                        details.songLength = arrangement.SongLength;
                        details.songName   = arrangement.SongName;
                        details.artistName = arrangement.ArtistName;
                        details.albumName  = arrangement.AlbumName;
                        details.albumYear  = arrangement.SongYear;
                        details.arrangements.Add(arrangementDetails);

                        //Apply toolkit information
                        details.toolkit = new ToolkitDetails
                        {
                            version         = tkInfo.PackageVersion,
                            author          = tkInfo.PackageAuthor,
                            comment         = tkInfo.PackageComment,
                            package_version = tkInfo.PackageVersion
                        };
                    }
                }

                sw.Stop();

                Logger.Log("Parsed {0} ({1}mb) in {2}ms and found {3} songs", fileInfo.Name, fileInfo.Length / 1024 / 1024, sw.ElapsedMilliseconds, detailsDict.Count);

                return(detailsDict);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Fills Songs with SongData.
        /// </summary>
        /// <param name="progressBar"> - Attach a progress bar to the loading process.</param>
        /// <returns> - Value of Songs</returns>
        public static Dictionary <string, SongData> ExtractSongData(ProgressBar progressBar = null)
        {
            // Init
            Songs.Clear();
            bool          progressBarAvailable = progressBar != null;
            List <string> allFiles             = Directory.GetFiles(Path.Combine(Settings.Settings.RocksmithLocation, "dlc"), "*_p.psarc", SearchOption.AllDirectories).ToList();


            // Setup Progressbar if passed in as a parameter.
            if (progressBarAvailable)
            {
                progressBar.Visible = true;
                progressBar.Minimum = 1;
                progressBar.Maximum = allFiles.Count;
                progressBar.Value   = 1;
                progressBar.Step    = 1;
            }


            // Look through every file in allFiles.
            ParallelLoopResult loopResult = Parallel.ForEach(allFiles, (file) =>
            {
                try
                {
                    using (PsarcFile psarc = new PsarcFile(file))
                    {
                        List <SongArrangement> ExtractedArrangementManifests = psarc.ExtractArrangementManifests(); // List every arrangement in the psarc. This is crucial for looking at song packs!

                        foreach (SongArrangement arrangement in ExtractedArrangementManifests)
                        {
                            SongData song = new SongData()
                            {
                                DLCKey     = arrangement.Attributes.SongKey,
                                Artist     = arrangement.Attributes.ArtistName,
                                AppID      = psarc.ExtractAppID(),
                                Title      = arrangement.Attributes.SongName,
                                Shipping   = arrangement.Attributes.Shipping,
                                SKU        = arrangement.Attributes.SKU,
                                CommonName = $"{arrangement.Attributes.ArtistName} - {arrangement.Attributes.SongName}"
                            };

                            if (song.DLCKey == null || song.CommonName == string.Empty || song.CommonName == " - " || song.Artist == string.Empty || song.Title == string.Empty || !song.Shipping) // Some songs have a glitched arrangment, so we skip it.
                            {
                                continue;
                            }

                            // Load all RS1 DLC and their ID so we can determine if the user owns it, and if we should display it accordingly.
                            if (psarc.ExtractToolkitInfo().PackageAuthor == "Ubisoft")
                            {
                                song.ODLC = true;
                                if (arrangement.Attributes.SKU == "RS1" && arrangement.Attributes.DLCRS1Key != null)
                                {
                                    song.RS1AppID = arrangement.Attributes.DLCRS1Key[0].WIN32;
                                }
                            }

                            // Add Song to Songs if it isn't already in it.
                            if (Songs.ContainsKey(song.DLCKey))
                            {
                                continue;
                            }
                            else if (song != null)
                            {
                                Songs.Add(song.DLCKey, song);
                            }
                        }
                    }
                }
                catch {} // We are reading the files too quick. Let's forget about it for now as we are just trying to get a rough count.
            });

            // Shutdown Progressbar
            if (progressBarAvailable)
            {
                progressBar.Visible = false;
                progressBar.Value   = progressBar.Minimum;
            }

            Songs = Songs.Where(song => song.Key != null).Distinct().ToDictionary(song => song.Key, song => song.Value); // Clear out duplicates, and any null values that got accidently set.

            return(Songs);
        }