Exemplo n.º 1
0
        private static Dictionary <表示レーン種別, int> _ノーツ数を算出して返す(SSTFormatCurrent.スコア score, ユーザ設定 ユーザ設定)
        {
            var ノーツ数 = new Dictionary <表示レーン種別, int>();

            foreach (表示レーン種別 lane in Enum.GetValues(typeof(表示レーン種別)))
            {
                ノーツ数.Add(lane, 0);
            }

            foreach (var chip in score.チップリスト)
            {
                var チップの対応表 = ユーザ設定.ドラムとチップと入力の対応表[chip.チップ種別];

                // AutoPlay ON のチップは、すべてがONである場合を除いて、カウントしない。
                if (ユーザ設定.AutoPlay[チップの対応表.AutoPlay種別])
                {
                    if (!(ユーザ設定.AutoPlayがすべてONである))
                    {
                        continue;
                    }
                }
                // AutoPlay OFF 時でもユーザヒットの対象にならないチップはカウントしない。
                if (!(チップの対応表.AutoPlayOFF.ユーザヒット))
                {
                    continue;
                }

                ノーツ数[チップの対応表.表示レーン種別]++;
            }

            return(ノーツ数);
        }
Exemplo n.º 2
0
                // 初期化。
                public static void 状態をリセットする()
                {
                    スコア    = null;
                    データ種別  = データ種別.DTX;
                    Random = new Random((int)(Stopwatch.GetTimestamp() % int.MaxValue));

                    行番号 = 0;

                    コマンド     = "";
                    コマンドzzなし = "";
                    zz16進数   = -1;
                    zz36進数   = -1;
                    パラメータ    = "";
                    コメント     = "";

                    小節番号    = 0;
                    チャンネル番号 = 0;

                    チップ種別    = チップ種別.Unknown;
                    小節解像度    = 384; // DTX の小節解像度は 384 固定
                    オブジェクト総数 = 0;
                    オブジェクト番号 = 0;

                    PAN定義マップ    = new Dictionary <int, int>();
                    VOLUME定義マップ = new Dictionary <int, int>();

                    BASEBPM  = 0.0;
                    BPM定義マップ = new Dictionary <int, double>();
                    BPM参照マップ = new Dictionary <チップ, int>();

                    小節長倍率マップ = new SortedDictionary <int, double>();
                }
Exemplo n.º 3
0
        private int _総ノーツ数を算出して返す(SSTFormatCurrent.スコア score, ユーザ設定 options)
        {
            int 総ノーツ数 = 0;

            foreach (var chip in score.チップリスト)
            {
                var チップの対応表 = options.ドラムとチップと入力の対応表[chip.チップ種別];

                // AutoPlay ON のチップは、
                if (options.AutoPlay[チップの対応表.AutoPlay種別])
                {
                    if (!(options.AutoPlayがすべてONである))
                    {
                        continue;                               // すべてがONである場合を除いて、カウントしない。
                    }
                }

                // AutoPlay OFF 時でもユーザヒットの対象にならないチップはカウントしない。
                if (!(チップの対応表.AutoPlayOFF.ユーザヒット))
                {
                    continue;
                }

                総ノーツ数++;
            }

            return(総ノーツ数);
        }
Exemplo n.º 4
0
        private static (double 最小BPM, double 最大BPM) _最小最大BPMを調べて返す(SSTFormatCurrent.スコア score)
        {
            var result = (最小BPM : double.MaxValue, 最大BPM : double.MinValue);

            var BPMchips = score.チップリスト.Where((c) => (c.チップ種別 == SSTFormatCurrent.チップ種別.BPM));

            foreach (var chip in BPMchips)
            {
                result.最小BPM = Math.Min(result.最小BPM, chip.BPM);
                result.最大BPM = Math.Max(result.最大BPM, chip.BPM);
            }

            if (result.最小BPM == double.MaxValue || result.最大BPM == double.MinValue)                     // BPMチップがひとつもなかった
            {
                double 初期BPM = SSTFormatCurrent.スコア.初期BPM;
                result = (初期BPM, 初期BPM);
            }

            return(result);
        }
Exemplo n.º 5
0
        protected override void データベースのアップグレードマイグレーションを行う(long 移行元DBバージョン)
        {
            switch (移行元DBバージョン)
            {
            case 2:
                #region " 2 → 3 "
                //----------------
                this.DataContext.ExecuteCommand("PRAGMA foreign_keys = OFF");
                this.DataContext.SubmitChanges();
                using (var transaction = this.Connection.BeginTransaction())
                {
                    try
                    {
                        // テータベースをアップデートしてデータを移行する。
                        this.DataContext.ExecuteCommand($"CREATE TABLE new_Songs {Song03.ColumnsList}");
                        this.DataContext.ExecuteCommand($"INSERT INTO new_Songs SELECT *,null FROM Songs");                                     // 追加されたカラムは null
                        this.DataContext.ExecuteCommand($"DROP TABLE Songs");
                        this.DataContext.ExecuteCommand($"ALTER TABLE new_Songs RENAME TO Songs");
                        this.DataContext.ExecuteCommand("PRAGMA foreign_keys = ON");
                        this.DataContext.SubmitChanges();

                        // すべてのレコードについて、追加されたカラムを更新する。
                        var song03s = base.DataContext.GetTable <Song03>();
                        foreach (var song03 in song03s)
                        {
                            var score = (SSTFormatCurrent.スコア)null;

                            #region " スコアを読み込む "
                            //----------------
                            var 拡張子名 = Path.GetExtension(song03.Path);
                            if (".sstf" == 拡張子名)
                            {
                                score = new SSTFormatCurrent.スコア(song03.Path);
                            }
                            else if (".dtx" == 拡張子名)
                            {
                                score = SSTFormatCurrent.DTXReader.ReadFromFile(song03.Path);
                            }
                            else
                            {
                                throw new Exception($"未対応のフォーマットファイルです。[{song03.Path.ToVariablePath().変数付きパス}]");
                            }
                            //----------------
                            #endregion

                            using ( score )
                            {
                                // Artist カラムの更新。
                                if (score.アーティスト名.Nullでも空でもない())
                                {
                                    song03.Artist = score.アーティスト名;
                                }
                                else
                                {
                                    song03.Artist = "";                                             // null不可
                                }
                            }
                        }
                        this.DataContext.SubmitChanges();

                        // 成功。
                        transaction.Commit();
                        Log.Info("Songs テーブルをアップデートしました。[2→3]");
                    }
                    catch
                    {
                        // 失敗。
                        transaction.Rollback();
                        Log.ERROR("Songs テーブルのアップデートに失敗しました。[2→3]");
                    }
                }
                //----------------
                #endregion
                break;

            case 1:
                #region " 1 → 2 "
                //----------------
                this.DataContext.ExecuteCommand("PRAGMA foreign_keys = OFF");
                this.DataContext.SubmitChanges();
                using (var transaction = this.Connection.BeginTransaction())
                {
                    try
                    {
                        // テータベースをアップデートしてデータを移行する。
                        this.DataContext.ExecuteCommand($"CREATE TABLE new_Songs {Song02.ColumnsList}");
                        this.DataContext.ExecuteCommand($"INSERT INTO new_Songs SELECT *,null FROM Songs");                                     // 追加されたカラムは null
                        this.DataContext.ExecuteCommand($"DROP TABLE Songs");
                        this.DataContext.ExecuteCommand($"ALTER TABLE new_Songs RENAME TO Songs");
                        this.DataContext.ExecuteCommand("PRAGMA foreign_keys = ON");
                        this.DataContext.SubmitChanges();

                        // すべてのレコードについて、追加されたカラムを更新する。
                        var song02s = base.DataContext.GetTable <Song02>();
                        foreach (var song02 in song02s)
                        {
                            var 拡張子名  = Path.GetExtension(song02.Path);
                            var score = (SSTFormatCurrent.スコア)null;

                            #region " スコアを読み込む "
                            //----------------
                            if (".sstf" == 拡張子名)
                            {
                                score = new SSTFormatCurrent.スコア(song02.Path);
                            }
                            else if (".dtx" == 拡張子名)
                            {
                                score = SSTFormatCurrent.DTXReader.ReadFromFile(song02.Path);
                            }
                            else
                            {
                                throw new Exception($"未対応のフォーマットファイルです。[{song02.Path.ToVariablePath().変数付きパス}]");
                            }
                            //----------------
                            #endregion

                            using ( score )
                            {
                                // PreImage カラムの更新。
                                if (score.プレビュー画像.Nullでも空でもない())
                                {
                                    // プレビュー画像は、曲ファイルからの相対パス。
                                    song02.PreImage = Path.Combine(Path.GetDirectoryName(song02.Path), score.プレビュー画像);
                                }
                                else
                                {
                                    song02.PreImage =
                                        (from ファイル名 in Directory.GetFiles(Path.GetDirectoryName(song02.Path))
                                         where _対応するサムネイル画像名.Any(thumbファイル名 => (Path.GetFileName(ファイル名).ToLower() == thumbファイル名))
                                         select ファイル名).FirstOrDefault();
                                }
                            }
                        }
                        this.DataContext.SubmitChanges();

                        // 成功。
                        transaction.Commit();
                        Log.Info("Songs テーブルをアップデートしました。[1→2]");
                    }
                    catch
                    {
                        // 失敗。
                        transaction.Rollback();
                        Log.ERROR("Songs テーブルのアップデートに失敗しました。[1→2]");
                    }
                }
                //----------------
                #endregion
                break;

            default:
                throw new Exception($"移行元DBのバージョン({移行元DBバージョン})がマイグレーションに未対応です。");
            }
        }
Exemplo n.º 6
0
        /// <summary>
        ///		指定した曲ファイルに対応するレコードがデータベースになければレコードを追加し、
        ///		あればそのレコードを更新する。
        /// </summary>
        public static void 曲を追加または更新する(VariablePath 曲ファイルパス, ユーザ設定 ユーザ設定)
        {
            try
            {
                using (var songdb = new SongDB())
                {
                    var 一パス検索クエリ = songdb.Songs.Where((song) => (song.Path == 曲ファイルパス.数なしパス));

                    if (0 == 一パス検索クエリ.Count())
                    {
                        // (A) 同一パスを持つレコードがDBになかった

                        var 調べる曲のハッシュ = _ファイルのハッシュを算出して返す(曲ファイルパス);

                        var 一ハッシュレコード = songdb.Songs.Where((song) => (song.HashId == 調べる曲のハッシュ)).SingleOrDefault();

                        if (null == 一ハッシュレコード)
                        {
                            #region " (A-a) 同一ハッシュを持つレコードがDBになかった → 新規追加 "
                            //----------------
                            var 拡張子名  = Path.GetExtension(曲ファイルパス.数なしパス);
                            var score = (SSTFormatCurrent.スコア)null;

                            #region " スコアを読み込む "
                            //----------------
                            if (".sstf" == 拡張子名)
                            {
                                score = new SSTFormatCurrent.スコア(曲ファイルパス.数なしパス);
                            }
                            else if (".dtx" == 拡張子名)
                            {
                                score = SSTFormatCurrent.DTXReader.ReadFromFile(曲ファイルパス.数なしパス);
                            }
                            else
                            {
                                throw new Exception($"未対応のフォーマットファイルです。[{曲ファイルパス.変数付きパス}]");
                            }
                            //----------------
                            #endregion

                            using ( score )
                            {
                                // Songs レコード新規追加。
                                var ノーツ数 = _ノーツ数を算出して返す(score, ユーザ設定);
                                var BPMs = _最小最大BPMを調べて返す(score);

                                songdb.Songs.InsertOnSubmit(
                                    new Song()
                                {
                                    HashId                 = _ファイルのハッシュを算出して返す(曲ファイルパス),
                                    Title                  = score.曲名,
                                    Path                   = 曲ファイルパス.数なしパス,
                                    LastWriteTime          = File.GetLastWriteTime(曲ファイルパス.数なしパス).ToString("G"),
                                    Level                  = score.難易度,
                                    MinBPM                 = BPMs.最小BPM,
                                    MaxBPM                 = BPMs.最大BPM,
                                    TotalNotes_LeftCymbal  = ノーツ数[表示レーン種別.LeftCrash],
                                    TotalNotes_HiHat       = ノーツ数[表示レーン種別.HiHat],
                                    TotalNotes_LeftPedal   = ノーツ数[表示レーン種別.Foot],
                                    TotalNotes_Snare       = ノーツ数[表示レーン種別.Snare],
                                    TotalNotes_Bass        = ノーツ数[表示レーン種別.Bass],
                                    TotalNotes_HighTom     = ノーツ数[表示レーン種別.Tom1],
                                    TotalNotes_LowTom      = ノーツ数[表示レーン種別.Tom2],
                                    TotalNotes_FloorTom    = ノーツ数[表示レーン種別.Tom3],
                                    TotalNotes_RightCymbal = ノーツ数[表示レーン種別.RightCrash],
                                    // プレビュー画像は、曲ファイルからの相対パス。
                                    PreImage = (score.プレビュー画像.Nullでも空でもない()) ? Path.Combine(Path.GetDirectoryName(曲ファイルパス.数なしパス), score.プレビュー画像) : "",
                                    Artist   = score.アーティスト名,
                                });
                            }

                            songdb.DataContext.SubmitChanges();

                            Log.Info($"DBに曲を追加しました。{曲ファイルパス.変数付きパス}");
                            //----------------
                            #endregion
                        }
                        else
                        {
                            #region " (A-b) 同一ハッシュを持つレコードがDBにあった → 更新 "
                            //----------------
                            var 拡張子名  = Path.GetExtension(曲ファイルパス.数なしパス);
                            var score = (SSTFormatCurrent.スコア)null;

                            #region " スコアを読み込む "
                            //----------------
                            if (".sstf" == 拡張子名)
                            {
                                score = new SSTFormatCurrent.スコア(曲ファイルパス.数なしパス);
                            }
                            else if (".dtx" == 拡張子名)
                            {
                                score = SSTFormatCurrent.DTXReader.ReadFromFile(曲ファイルパス.数なしパス);
                            }
                            else
                            {
                                throw new Exception($"未対応のフォーマットファイルです。[{曲ファイルパス.変数付きパス}]");
                            }
                            //----------------
                            #endregion

                            using ( score )
                            {
                                // Songs レコード更新。
                                var ノーツ数 = _ノーツ数を算出して返す(score, ユーザ設定);
                                var BPMs = _最小最大BPMを調べて返す(score);
                                var song = 一ハッシュレコード;

                                song.Title                  = score.曲名;
                                song.Path                   = 曲ファイルパス.数なしパス;
                                song.LastWriteTime          = File.GetLastWriteTime(曲ファイルパス.数なしパス).ToString("G");
                                song.Level                  = score.難易度;
                                song.MinBPM                 = BPMs.最小BPM;
                                song.MaxBPM                 = BPMs.最大BPM;
                                song.TotalNotes_LeftCymbal  = ノーツ数[表示レーン種別.LeftCrash];
                                song.TotalNotes_HiHat       = ノーツ数[表示レーン種別.HiHat];
                                song.TotalNotes_LeftPedal   = ノーツ数[表示レーン種別.Foot];
                                song.TotalNotes_Snare       = ノーツ数[表示レーン種別.Snare];
                                song.TotalNotes_Bass        = ノーツ数[表示レーン種別.Bass];
                                song.TotalNotes_HighTom     = ノーツ数[表示レーン種別.Tom1];
                                song.TotalNotes_LowTom      = ノーツ数[表示レーン種別.Tom2];
                                song.TotalNotes_FloorTom    = ノーツ数[表示レーン種別.Tom3];
                                song.TotalNotes_RightCymbal = ノーツ数[表示レーン種別.RightCrash];
                                // プレビュー画像は、曲ファイルからの相対パス。
                                song.PreImage = (score.プレビュー画像.Nullでも空でもない()) ? Path.Combine(Path.GetDirectoryName(曲ファイルパス.数なしパス), score.プレビュー画像) : "";
                                song.Artist   = score.アーティスト名;
                            }

                            songdb.DataContext.SubmitChanges();

                            Log.Info($"パスが異なりハッシュが同一であるレコードが検出されたため、曲の情報を更新しました。{曲ファイルパス.変数付きパス}");
                            //----------------
                            #endregion
                        }
                    }
                    else
                    {
                        // (B) 同一パスを持つレコードがDBにあった

                        var record = 一パス検索クエリ.Single();

                        string レコードの最終更新日時 = record.LastWriteTime;
                        string 調べる曲の最終更新日時 = File.GetLastWriteTime(曲ファイルパス.数なしパス).ToString("G");

                        if (レコードの最終更新日時 != 調べる曲の最終更新日時)
                        {
                            #region " (B-a) 最終更新日時が変更されている → 更新 "
                            //----------------
                            var 拡張子名  = Path.GetExtension(曲ファイルパス.数なしパス);
                            var score = (SSTFormatCurrent.スコア)null;

                            #region " スコアを読み込む "
                            //----------------
                            if (".sstf" == 拡張子名)
                            {
                                score = new SSTFormatCurrent.スコア(曲ファイルパス.数なしパス);
                            }
                            else if (".dtx" == 拡張子名)
                            {
                                score = SSTFormatCurrent.DTXReader.ReadFromFile(曲ファイルパス.数なしパス);
                            }
                            else
                            {
                                throw new Exception($"未対応のフォーマットファイルです。[{曲ファイルパス.変数付きパス}]");
                            }
                            //----------------
                            #endregion

                            using ( score )
                            {
                                var hash = _ファイルのハッシュを算出して返す(曲ファイルパス);
                                var ノーツ数 = _ノーツ数を算出して返す(score, ユーザ設定);
                                var BPMs = _最小最大BPMを調べて返す(score);

                                // HashId 以外のカラムを更新する。
                                record.Title                  = score.曲名;
                                record.LastWriteTime          = 調べる曲の最終更新日時;
                                record.Level                  = score.難易度;
                                record.MinBPM                 = BPMs.最小BPM;
                                record.MaxBPM                 = BPMs.最大BPM;
                                record.TotalNotes_LeftCymbal  = ノーツ数[表示レーン種別.LeftCrash];
                                record.TotalNotes_HiHat       = ノーツ数[表示レーン種別.HiHat];
                                record.TotalNotes_LeftPedal   = ノーツ数[表示レーン種別.Foot];
                                record.TotalNotes_Snare       = ノーツ数[表示レーン種別.Snare];
                                record.TotalNotes_Bass        = ノーツ数[表示レーン種別.Bass];
                                record.TotalNotes_HighTom     = ノーツ数[表示レーン種別.Tom1];
                                record.TotalNotes_LowTom      = ノーツ数[表示レーン種別.Tom2];
                                record.TotalNotes_FloorTom    = ノーツ数[表示レーン種別.Tom3];
                                record.TotalNotes_RightCymbal = ノーツ数[表示レーン種別.RightCrash];
                                // プレビュー画像は、曲ファイルからの相対パス。
                                record.PreImage = (score.プレビュー画像.Nullでも空でもない()) ? Path.Combine(Path.GetDirectoryName(曲ファイルパス.数なしパス), score.プレビュー画像) : "";
                                record.Artist   = score.アーティスト名;

                                if (hash != record.HashId)
                                {
                                    // ハッシュはキーなので、これが変わったら、古いレコードを削除して、新しいレコードを追加する。
                                    var newRecord = record.Clone();
                                    songdb.Songs.DeleteOnSubmit(record);
                                    songdb.DataContext.SubmitChanges();                                         // 一度Submitして先にレコード削除を確定しないと、次のInsertがエラーになる。(PathカラムはUnique属性なので)

                                    newRecord.HashId = hash;
                                    songdb.Songs.InsertOnSubmit(newRecord);
                                }

                                songdb.DataContext.SubmitChanges();
                            }

                            Log.Info($"最終更新日時が変更されているため、曲の情報を更新しました。{曲ファイルパス.変数付きパス}");
                            //----------------
                            #endregion
                        }
                        else
                        {
                            #region " (B-b) それ以外 "
                            //----------------
                            //----------------
                            #endregion
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.ERROR($"曲DBへの曲の追加に失敗しました。({e.Message})[{曲ファイルパス.変数付きパス}]");
                throw;
            }
        }
Exemplo n.º 7
0
 public void スコアと設定を反映する(SSTFormatCurrent.スコア 譜面, ユーザ設定 設定)
 {
     this.総ノーツ数  = (null != 譜面 && null != 設定) ? this._総ノーツ数を算出して返す(譜面, 設定) : 0;
     this._譜面レベル = 譜面?.難易度 ?? 0.5;
 }