Ejemplo n.º 1
0
        public void StartAsync(MediaDevice device = null)
        {
            RunningTask = Task.Run(() =>
            {
                IsRunning = true;
                string questSongDirectoryPath = null;

                if (device != null)
                {
                    var base_folder        = device.GetDirectories(@"\")[0];
                    questSongDirectoryPath = $"{base_folder}{Oculus.QuestSongDirectoryName}";
                }

                var file   = new FileInfo(SongLogFilePath);
                var length = file.Length;

                using var stream = File.Open(SongLogFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                using var reader = new StreamReader(stream);

                var session = new Session();

                while (IsRunning)
                {
                    var line = reader.ReadLine();

                    var songLevelLineHint       = "LogTemp: Warning: Song level str";
                    var songNameLineHint        = "LogTemp: Loading song";
                    var songScoreDetailLineHint = "LogTemp: Warning: Notes missed :";
                    var songScoreLineHint       = "raw distance =";

                    if (line.Contains(songLevelLineHint))
                    {
                        session            = new Session();
                        session.Song.Level = line.Substring(line.IndexOf(songLevelLineHint) + songLevelLineHint.Length)
                                             .Trim(' ', '.');
                    }
                    else if (line.Contains(songScoreDetailLineHint))
                    {
                        //        LogTemp: Warning: Notes missed : 0 / Notes hit  : 784 / Notes not processed : 0 / hit accuracy : 0.015131 / percentage : 0.848690 / hit speed : 1077.700073 / percentage : 0.698357 / combos : 7
                        var startIndex      = line.IndexOf(songScoreDetailLineHint) + songScoreDetailLineHint.Length;
                        var endIndex        = line.IndexOf(" / Notes hit  : ");
                        session.NotesMissed =
                            int.Parse(line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.'));

                        startIndex       = line.IndexOf(" / Notes hit  : ") + " / Notes hit  : ".Length;
                        endIndex         = line.IndexOf(" / Notes not processed : ");
                        session.NotesHit = int.Parse(line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.'));

                        startIndex = line.IndexOf(" / Notes not processed : ") + " / Notes not processed : ".Length;
                        endIndex   = line.IndexOf(" / hit accuracy : ");
                        session.NotesNotProcessed =
                            int.Parse(line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.'));

                        startIndex          = line.IndexOf(" / hit accuracy : ") + " / hit accuracy : ".Length;
                        endIndex            = line.IndexOf(" / percentage : ");
                        session.HitAccuracy = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        startIndex          = line.IndexOf(" / hit accuracy : ") + " / hit accuracy : ".Length;
                        endIndex            = startIndex + 9;
                        session.HitAccuracy = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        startIndex         = endIndex + 14;
                        endIndex           = startIndex + 9;
                        session.Percentage = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        startIndex       = endIndex + 14;
                        endIndex         = startIndex + 12;
                        session.HitSpeed = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        startIndex          = endIndex + 15;
                        endIndex            = startIndex + 8;
                        session.Percentage2 = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        startIndex     = endIndex + 12;
                        endIndex       = line.Length;
                        var content    = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');
                        session.Combos = int.Parse(content);
                    }
                    else if (line.Contains(songNameLineHint))
                    {
                        var songOggPath = line.Substring(line.IndexOf(songNameLineHint) + songNameLineHint.Length)
                                          .Trim(' ', '.');
                        var songDirectoryPath = Path.GetDirectoryName(songOggPath);

                        // if log file is coming from quest, we need to download song before calculating hash file
                        if (device != null)
                        {
                            var songName         = songDirectoryPath.Split('\\').Last();
                            var tempDir          = Path.GetDirectoryName(SongLogFilePath);
                            var tempSongFolder   = tempDir + "\\" + songName;
                            var oculusSongFolder = questSongDirectoryPath + "\\" + songName;
                            if (!device.DirectoryExists(oculusSongFolder))
                            {
                                continue;
                            }
                            device.DownloadFolder(oculusSongFolder, tempSongFolder);
                            songDirectoryPath = tempSongFolder;
                        }

                        var songDirectory = new DirectoryInfo(songDirectoryPath);
                        if (!songDirectory.Exists)
                        {
                            continue;
                        }

                        var songDatFiles = songDirectory.EnumerateFiles("*.dat");

                        var filesHashs        = songDatFiles.Select(ComputeMd5).OrderBy(hash => hash);
                        var concatenatedHashs = string.Concat(filesHashs);

                        session.Song.Hash = ComputeMd5(concatenatedHashs);
                        Trace.WriteLine(
                            $"{DateTime.Now} - New file - Hash: {session.Song.Hash}; File: {songDirectoryPath}");
                    }
                    else if (line.Contains(songScoreLineHint))
                    {
                        var startIndex = line.IndexOf(songScoreLineHint) + songScoreLineHint.Length;
                        var endIndex   = line.IndexOf("and adjusted distance =");

                        session.Score = line.Substring(startIndex, endIndex - startIndex).Trim(' ', '.');

                        if (session.Song.Hash is null)
                        {
                            continue;
                        }
                        Trace.WriteLine(
                            $"{DateTime.Now} - New session - Hash: {session.Song.Hash}; Level: {session.Song.Level}; Score: {session.Score}");
                        OnNewSession?.Invoke(session);
                        line = reader.ReadLine();
                    }

                    while (reader.EndOfStream)
                    {
                        file = new FileInfo(SongLogFilePath);

                        if (file.Length < length)
                        {
                            stream.Seek(0, SeekOrigin.Begin);
                            reader.DiscardBufferedData();
                        }

                        length = file.Length;

                        Thread.Sleep(WaitForNewContentMilliseconds);

                        // there will be no new data once the end of file is reach for oculus log
                        if (device != null)
                        {
                            IsRunning = false;
                            return;
                        }
                    }
                }
            });

            // Waiting for oculus send score to finish before continuig and thus removing temp folder
            if (device != null)
            {
                RunningTask.Wait();
            }
        }