2 using System.Collections.Generic;
\r
3 using System.Globalization;
\r
5 using System.Diagnostics;
\r
7 using System.Drawing;
\r
8 using System.Threading;
\r
13 internal class CSongs管理
\r
17 public int nSongsDBから取得できたスコア数
\r
22 public int nSongsDBへ出力できたスコア数
\r
27 public int nスコアキャッシュから反映できたスコア数
\r
32 public int nファイルから反映できたスコア数
\r
37 public int n検索されたスコア数
\r
42 public int n検索された曲ノード数
\r
48 public List<Cスコア> listSongsDB; // songs.dbから構築されるlist
\r
49 public List<C曲リストノード> list曲ルート; // 起動時にフォルダ検索して構築されるlist
\r
50 public bool bIsSuspending // 外部スレッドから、内部スレッドのsuspendを指示する時にtrueにする
\r
51 { // 再開時は、これをfalseにしてから、次のautoReset.Set()を実行する
\r
56 private AutoResetEvent autoReset;
\r
57 public AutoResetEvent AutoReset
\r
73 this.listSongsDB = new List<Cスコア>();
\r
74 this.list曲ルート = new List<C曲リストノード>();
\r
75 this.n検索された曲ノード数 = 0;
\r
76 this.n検索されたスコア数 = 0;
\r
77 this.bIsSuspending = false; // #27060
\r
78 this.autoReset = new AutoResetEvent( true ); // #27060
\r
84 #region [ SongsDB(songs.db) を読み込む ]
\r
86 public void tSongsDBを読み込む( string SongsDBファイル名 )
\r
88 this.nSongsDBから取得できたスコア数 = 0;
\r
89 if( File.Exists( SongsDBファイル名 ) )
\r
91 BinaryReader br = null;
\r
94 br = new BinaryReader( File.OpenRead( SongsDBファイル名 ) );
\r
95 if ( !br.ReadString().Equals( SONGSDB_VERSION ) )
\r
97 throw new InvalidDataException( "ヘッダが異なります。" );
\r
99 this.listSongsDB = new List<Cスコア>();
\r
105 Cスコア item = this.tSongsDBからスコアを1つ読み込む( br );
\r
106 this.listSongsDB.Add( item );
\r
107 this.nSongsDBから取得できたスコア数++;
\r
109 catch( EndOfStreamException )
\r
122 //-----------------
\r
125 #region [ 曲を検索してリストを作成する ]
\r
126 //-----------------
\r
127 public void t曲を検索してリストを作成する( string str基点フォルダ, bool b子BOXへ再帰する )
\r
129 this.t曲を検索してリストを作成する( str基点フォルダ, b子BOXへ再帰する, this.list曲ルート, null );
\r
131 private void t曲を検索してリストを作成する( string str基点フォルダ, bool b子BOXへ再帰する, List<C曲リストノード> listノードリスト, C曲リストノード node親 )
\r
133 if( !str基点フォルダ.EndsWith( @"\" ) )
\r
134 str基点フォルダ = str基点フォルダ + @"\";
\r
136 DirectoryInfo info = new DirectoryInfo( str基点フォルダ );
\r
138 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
139 Trace.TraceInformation( "基点フォルダ: " + str基点フォルダ );
\r
141 #region [ a.フォルダ内に set.def が存在する場合 → set.def からノード作成]
\r
142 //-----------------------------
\r
143 string path = str基点フォルダ + "set.def";
\r
144 if( File.Exists( path ) )
\r
146 CSetDef def = new CSetDef( path );
\r
147 new FileInfo( path );
\r
148 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
150 Trace.TraceInformation( "set.def検出 : {0}", path );
\r
155 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
157 autoReset.WaitOne();
\r
159 for( int i = 0; i < def.blocks.Count; i++ )
\r
161 CSetDef.CBlock block = def.blocks[ i ];
\r
162 C曲リストノード item = new C曲リストノード();
\r
163 item.eノード種別 = C曲リストノード.Eノード種別.SCORE;
\r
164 item.strタイトル = block.Title;
\r
165 item.strジャンル = block.Genre;
\r
167 item.col文字色 = block.FontColor;
\r
168 item.SetDefのブロック番号 = i;
\r
169 item.pathSetDefの絶対パス = path;
\r
170 item.r親ノード = node親;
\r
171 for( int j = 0; j < 5; j++ )
\r
173 if( !string.IsNullOrEmpty( block.File[ j ] ) )
\r
175 string str2 = str基点フォルダ + block.File[ j ];
\r
176 if( File.Exists( str2 ) )
\r
178 item.ar難易度ラベル[ j ] = block.Label[ j ];
\r
179 item.arスコア[ j ] = new Cスコア();
\r
180 item.arスコア[ j ].ファイル情報.ファイルの絶対パス = str2;
\r
181 item.arスコア[ j ].ファイル情報.フォルダの絶対パス = Path.GetFullPath( Path.GetDirectoryName( str2 ) ) + @"\";
\r
182 FileInfo info2 = new FileInfo( str2 );
\r
183 item.arスコア[ j ].ファイル情報.ファイルサイズ = info2.Length;
\r
184 item.arスコア[ j ].ファイル情報.最終更新日時 = info2.LastWriteTime;
\r
185 string str3 = str2 + ".score.ini";
\r
186 if( File.Exists( str3 ) )
\r
188 FileInfo info3 = new FileInfo( str3 );
\r
189 item.arスコア[ j ].ScoreIni情報.ファイルサイズ = info3.Length;
\r
190 item.arスコア[ j ].ScoreIni情報.最終更新日時 = info3.LastWriteTime;
\r
197 item.arスコア[ j ] = null;
\r
201 if( item.nスコア数 > 0 )
\r
203 listノードリスト.Add( item );
\r
204 this.n検索された曲ノード数++;
\r
205 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
207 StringBuilder builder = new StringBuilder( 0x200 );
\r
208 builder.Append( string.Format( "nID#{0:D3}", item.nID ) );
\r
209 if( item.r親ノード != null )
\r
211 builder.Append( string.Format( "(in#{0:D3}):", item.r親ノード.nID ) );
\r
215 builder.Append( "(onRoot):" );
\r
217 if( ( item.strタイトル != null ) && ( item.strタイトル.Length > 0 ) )
\r
219 builder.Append( " SONG, Title=" + item.strタイトル );
\r
221 if( ( item.strジャンル != null ) && ( item.strジャンル.Length > 0 ) )
\r
223 builder.Append( ", Genre=" + item.strジャンル );
\r
225 if( item.col文字色 != Color.White )
\r
227 builder.Append( ", FontColor=" + item.col文字色 );
\r
229 Trace.TraceInformation( builder.ToString() );
\r
233 for( int k = 0; k < 5; k++ )
\r
235 if( item.arスコア[ k ] != null )
\r
237 Cスコア cスコア = item.arスコア[ k ];
\r
238 builder.Remove( 0, builder.Length );
\r
239 builder.Append( string.Format( "ブロック{0}-{1}:", item.SetDefのブロック番号 + 1, k + 1 ) );
\r
240 builder.Append( " Label=" + item.ar難易度ラベル[ k ] );
\r
241 builder.Append( ", File=" + cスコア.ファイル情報.ファイルの絶対パス );
\r
242 builder.Append( ", Size=" + cスコア.ファイル情報.ファイルサイズ );
\r
243 builder.Append( ", LastUpdate=" + cスコア.ファイル情報.最終更新日時 );
\r
244 Trace.TraceInformation( builder.ToString() );
\r
258 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
264 //-----------------------------
\r
267 #region [ b.フォルダ内に set.def が存在しない場合 → 個別ファイルからノード作成 ]
\r
268 //-----------------------------
\r
271 foreach( FileInfo fileinfo in info.GetFiles() )
\r
273 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
275 autoReset.WaitOne();
\r
277 string strExt = fileinfo.Extension.ToLower();
\r
278 if( ( strExt.Equals( ".dtx" ) || strExt.Equals( ".gda" ) ) || ( ( strExt.Equals( ".g2d" ) || strExt.Equals( ".bms" ) ) || strExt.Equals( ".bme" ) ) )
\r
280 C曲リストノード c曲リストノード = new C曲リストノード();
\r
281 c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE;
\r
282 c曲リストノード.nスコア数 = 1;
\r
283 c曲リストノード.r親ノード = node親;
\r
284 c曲リストノード.arスコア[ 0 ] = new Cスコア();
\r
285 c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス = str基点フォルダ + fileinfo.Name;
\r
286 c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = str基点フォルダ;
\r
287 c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ = fileinfo.Length;
\r
288 c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 = fileinfo.LastWriteTime;
\r
289 string strFileNameScoreIni = c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス + ".score.ini";
\r
290 if( File.Exists( strFileNameScoreIni ) )
\r
292 FileInfo infoScoreIni = new FileInfo( strFileNameScoreIni );
\r
293 c曲リストノード.arスコア[ 0 ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length;
\r
294 c曲リストノード.arスコア[ 0 ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime;
\r
297 listノードリスト.Add( c曲リストノード );
\r
298 this.n検索された曲ノード数++;
\r
299 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
304 StringBuilder sb = new StringBuilder( 0x100 );
\r
305 sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );
\r
306 if( c曲リストノード.r親ノード != null )
\r
308 sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );
\r
312 sb.Append( "(onRoot):" );
\r
314 sb.Append( " SONG, File=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス );
\r
315 sb.Append( ", Size=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ );
\r
316 sb.Append( ", LastUpdate=" + c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 );
\r
317 Trace.TraceInformation( sb.ToString() );
\r
325 else if( strExt.Equals( ".mid" ) || strExt.Equals( ".smf" ))
\r
331 //-----------------------------
\r
334 foreach( DirectoryInfo infoDir in info.GetDirectories() )
\r
336 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
338 autoReset.WaitOne();
\r
341 #region [ a. "dtxfiles." で始まるフォルダの場合 ]
\r
342 //-----------------------------
\r
343 if( infoDir.Name.ToLower().StartsWith( "dtxfiles." ) )
\r
345 C曲リストノード c曲リストノード = new C曲リストノード();
\r
346 c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;
\r
347 c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = true;
\r
348 c曲リストノード.strタイトル = infoDir.Name.Substring( 9 );
\r
349 c曲リストノード.nスコア数 = 1;
\r
350 c曲リストノード.r親ノード = node親;
\r
351 c曲リストノード.list子リスト = new List<C曲リストノード>();
\r
352 c曲リストノード.arスコア[ 0 ] = new Cスコア();
\r
353 c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";
\r
354 c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = c曲リストノード.strタイトル;
\r
355 c曲リストノード.arスコア[ 0 ].譜面情報.コメント =
\r
356 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?
\r
358 "Enter into the BOX.";
\r
359 listノードリスト.Add(c曲リストノード);
\r
360 if( File.Exists( infoDir.FullName + @"\box.def" ) )
\r
362 CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );
\r
363 if( ( boxdef.Title != null ) && ( boxdef.Title.Length > 0 ) )
\r
365 c曲リストノード.strタイトル = boxdef.Title;
\r
367 if( ( boxdef.Genre != null ) && ( boxdef.Genre.Length > 0 ) )
\r
369 c曲リストノード.strジャンル = boxdef.Genre;
\r
371 if( boxdef.Color != Color.White )
\r
373 c曲リストノード.col文字色 = boxdef.Color;
\r
375 if( ( boxdef.Artist != null ) && ( boxdef.Artist.Length > 0 ) )
\r
377 c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;
\r
379 if( ( boxdef.Comment != null ) && ( boxdef.Comment.Length > 0 ) )
\r
381 c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;
\r
383 if( ( boxdef.Preimage != null ) && ( boxdef.Preimage.Length > 0 ) )
\r
385 c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;
\r
387 if( ( boxdef.Premovie != null ) && ( boxdef.Premovie.Length > 0 ) )
\r
389 c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;
\r
391 if( ( boxdef.Presound != null ) && ( boxdef.Presound.Length > 0 ) )
\r
393 c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;
\r
395 if( boxdef.PerfectRange >= 0 )
\r
397 c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;
\r
399 if( boxdef.GreatRange >= 0 )
\r
401 c曲リストノード.nGreat範囲ms = boxdef.GreatRange;
\r
403 if( boxdef.GoodRange >= 0 )
\r
405 c曲リストノード.nGood範囲ms = boxdef.GoodRange;
\r
407 if( boxdef.PoorRange >= 0 )
\r
409 c曲リストノード.nPoor範囲ms = boxdef.PoorRange;
\r
412 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
417 StringBuilder sb = new StringBuilder( 0x100 );
\r
418 sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );
\r
419 if( c曲リストノード.r親ノード != null )
\r
421 sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );
\r
425 sb.Append( "(onRoot):" );
\r
427 sb.Append( " BOX, Title=" + c曲リストノード.strタイトル );
\r
428 sb.Append( ", Folder=" + c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
429 sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );
\r
430 Trace.TraceInformation( sb.ToString() );
\r
439 this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );
\r
442 //-----------------------------
\r
445 #region [ b.box.def を含むフォルダの場合 ]
\r
446 //-----------------------------
\r
447 else if( File.Exists( infoDir.FullName + @"\box.def" ) )
\r
449 CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );
\r
450 C曲リストノード c曲リストノード = new C曲リストノード();
\r
451 c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;
\r
452 c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = false;
\r
453 c曲リストノード.strタイトル = boxdef.Title;
\r
454 c曲リストノード.strジャンル = boxdef.Genre;
\r
455 c曲リストノード.col文字色 = boxdef.Color;
\r
456 c曲リストノード.nスコア数 = 1;
\r
457 c曲リストノード.arスコア[ 0 ] = new Cスコア();
\r
458 c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";
\r
459 c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = boxdef.Title;
\r
460 c曲リストノード.arスコア[ 0 ].譜面情報.ジャンル = boxdef.Genre;
\r
461 c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;
\r
462 c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;
\r
463 c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;
\r
464 c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;
\r
465 c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;
\r
466 c曲リストノード.r親ノード = node親;
\r
467 c曲リストノード.list子リスト = new List<C曲リストノード>();
\r
468 c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;
\r
469 c曲リストノード.nGreat範囲ms = boxdef.GreatRange;
\r
470 c曲リストノード.nGood範囲ms = boxdef.GoodRange;
\r
471 c曲リストノード.nPoor範囲ms = boxdef.PoorRange;
\r
472 listノードリスト.Add( c曲リストノード );
\r
473 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
475 Trace.TraceInformation( "box.def検出 : {0}", infoDir.FullName + @"\box.def" );
\r
479 StringBuilder sb = new StringBuilder( 0x400 );
\r
480 sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );
\r
481 if( c曲リストノード.r親ノード != null )
\r
483 sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );
\r
487 sb.Append( "(onRoot):" );
\r
489 sb.Append( "BOX, Title=" + c曲リストノード.strタイトル );
\r
490 if( ( c曲リストノード.strジャンル != null ) && ( c曲リストノード.strジャンル.Length > 0 ) )
\r
492 sb.Append( ", Genre=" + c曲リストノード.strジャンル );
\r
494 if( ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名.Length > 0 ) )
\r
496 sb.Append( ", Artist=" + c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 );
\r
498 if( ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント.Length > 0 ) )
\r
500 sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );
\r
502 if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage.Length > 0 ) )
\r
504 sb.Append( ", Preimage=" + c曲リストノード.arスコア[ 0 ].譜面情報.Preimage );
\r
506 if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie.Length > 0 ) )
\r
508 sb.Append( ", Premovie=" + c曲リストノード.arスコア[ 0 ].譜面情報.Premovie );
\r
510 if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound.Length > 0 ) )
\r
512 sb.Append( ", Presound=" + c曲リストノード.arスコア[ 0 ].譜面情報.Presound );
\r
514 if( c曲リストノード.col文字色 != ColorTranslator.FromHtml( "White" ) )
\r
516 sb.Append( ", FontColor=" + c曲リストノード.col文字色 );
\r
518 if( c曲リストノード.nPerfect範囲ms != -1 )
\r
520 sb.Append( ", Perfect=" + c曲リストノード.nPerfect範囲ms + "ms" );
\r
522 if( c曲リストノード.nGreat範囲ms != -1 )
\r
524 sb.Append( ", Great=" + c曲リストノード.nGreat範囲ms + "ms" );
\r
526 if( c曲リストノード.nGood範囲ms != -1 )
\r
528 sb.Append( ", Good=" + c曲リストノード.nGood範囲ms + "ms" );
\r
530 if( c曲リストノード.nPoor範囲ms != -1 )
\r
532 sb.Append( ", Poor=" + c曲リストノード.nPoor範囲ms + "ms" );
\r
534 Trace.TraceInformation( sb.ToString() );
\r
543 this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );
\r
546 //-----------------------------
\r
549 #region [ c.通常フォルダの場合 ]
\r
550 //-----------------------------
\r
553 this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, listノードリスト, node親 );
\r
555 //-----------------------------
\r
559 //-----------------
\r
561 #region [ スコアキャッシュを曲リストに反映する ]
\r
562 //-----------------
\r
563 public void tスコアキャッシュを曲リストに反映する()
\r
565 this.nスコアキャッシュから反映できたスコア数 = 0;
\r
566 this.tスコアキャッシュを曲リストに反映する( this.list曲ルート );
\r
568 private void tスコアキャッシュを曲リストに反映する( List<C曲リストノード> ノードリスト )
\r
570 using( List<C曲リストノード>.Enumerator enumerator = ノードリスト.GetEnumerator() )
\r
572 while( enumerator.MoveNext() )
\r
574 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
576 autoReset.WaitOne();
\r
579 C曲リストノード node = enumerator.Current;
\r
580 if( node.eノード種別 == C曲リストノード.Eノード種別.BOX )
\r
582 this.tスコアキャッシュを曲リストに反映する( node.list子リスト );
\r
584 else if( ( node.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( node.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
\r
586 Predicate<Cスコア> match = null;
\r
587 for( int lv = 0; lv < 5; lv++ )
\r
589 if( node.arスコア[ lv ] != null )
\r
591 if( match == null )
\r
593 match = delegate( Cスコア sc )
\r
597 ( sc.ファイル情報.ファイルの絶対パス.Equals( node.arスコア[ lv ].ファイル情報.ファイルの絶対パス )
\r
598 && sc.ファイル情報.ファイルサイズ.Equals( node.arスコア[ lv ].ファイル情報.ファイルサイズ ) )
\r
599 && ( sc.ファイル情報.最終更新日時.Equals( node.arスコア[ lv ].ファイル情報.最終更新日時 )
\r
600 && sc.ScoreIni情報.ファイルサイズ.Equals( node.arスコア[ lv ].ScoreIni情報.ファイルサイズ ) ) )
\r
601 && sc.ScoreIni情報.最終更新日時.Equals( node.arスコア[ lv ].ScoreIni情報.最終更新日時 );
\r
604 int nMatched = this.listSongsDB.FindIndex( match );
\r
605 if( nMatched == -1 )
\r
607 //Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );
\r
608 if ( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
610 Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );
\r
615 node.arスコア[ lv ].譜面情報 = this.listSongsDB[ nMatched ].譜面情報;
\r
616 node.arスコア[ lv ].bSongDBにキャッシュがあった = true;
\r
617 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
619 Trace.TraceInformation( "songs.db から転記しました。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );
\r
621 this.nスコアキャッシュから反映できたスコア数++;
\r
622 if( node.arスコア[ lv ].ScoreIni情報.最終更新日時 != this.listSongsDB[ nMatched ].ScoreIni情報.最終更新日時 )
\r
624 string strFileNameScoreIni = node.arスコア[ lv ].ファイル情報.ファイルの絶対パス + ".score.ini";
\r
627 CScoreIni scoreIni = new CScoreIni( strFileNameScoreIni );
\r
628 scoreIni.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();
\r
629 for( int i = 0; i < 3; i++ )
\r
631 int nSectionHiSkill = ( i * 2 ) + 1;
\r
632 if( scoreIni.stセクション[ nSectionHiSkill ].b演奏にMIDI入力を使用した
\r
633 || scoreIni.stセクション[ nSectionHiSkill ].b演奏にキーボードを使用した
\r
634 || scoreIni.stセクション[ nSectionHiSkill ].b演奏にジョイパッドを使用した
\r
635 || scoreIni.stセクション[ nSectionHiSkill ].b演奏にマウスを使用した )
\r
637 node.arスコア[ lv ].譜面情報.最大ランク[ i ] =
\r
638 (scoreIni.stファイル.BestRank[i] != (int)CScoreIni.ERANK.UNKNOWN)?
\r
639 (int)scoreIni.stファイル.BestRank[i] : CScoreIni.tランク値を計算して返す( scoreIni.stセクション[ nSectionHiSkill ] );
\r
643 node.arスコア[ lv ].譜面情報.最大ランク[ i ] = (int)CScoreIni.ERANK.UNKNOWN;
\r
645 node.arスコア[ lv ].譜面情報.最大スキル[ i ] = scoreIni.stセクション[ nSectionHiSkill ].db演奏型スキル値;
\r
646 node.arスコア[ lv ].譜面情報.フルコンボ[ i ] = scoreIni.stセクション[ nSectionHiSkill ].bフルコンボである;
\r
648 node.arスコア[ lv ].譜面情報.演奏回数.Drums = scoreIni.stファイル.PlayCountDrums;
\r
649 node.arスコア[ lv ].譜面情報.演奏回数.Guitar = scoreIni.stファイル.PlayCountGuitar;
\r
650 node.arスコア[ lv ].譜面情報.演奏回数.Bass = scoreIni.stファイル.PlayCountBass;
\r
651 for( int j = 0; j < 5; j++ )
\r
653 node.arスコア[ lv ].譜面情報.演奏履歴[ j ] = scoreIni.stファイル.History[ j ];
\r
655 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
657 Trace.TraceInformation( "演奏記録ファイルから HiSkill 情報と演奏履歴を取得しました。({0})", strFileNameScoreIni );
\r
662 Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。({0})", strFileNameScoreIni );
\r
672 private Cスコア tSongsDBからスコアを1つ読み込む( BinaryReader br )
\r
674 Cスコア cスコア = new Cスコア();
\r
675 cスコア.ファイル情報.ファイルの絶対パス = br.ReadString();
\r
676 cスコア.ファイル情報.フォルダの絶対パス = br.ReadString();
\r
677 cスコア.ファイル情報.最終更新日時 = new DateTime( br.ReadInt64() );
\r
678 cスコア.ファイル情報.ファイルサイズ = br.ReadInt64();
\r
679 cスコア.ScoreIni情報.最終更新日時 = new DateTime( br.ReadInt64() );
\r
680 cスコア.ScoreIni情報.ファイルサイズ = br.ReadInt64();
\r
681 cスコア.譜面情報.タイトル = br.ReadString();
\r
682 cスコア.譜面情報.アーティスト名 = br.ReadString();
\r
683 cスコア.譜面情報.コメント = br.ReadString();
\r
684 cスコア.譜面情報.ジャンル = br.ReadString();
\r
685 cスコア.譜面情報.Preimage = br.ReadString();
\r
686 cスコア.譜面情報.Premovie = br.ReadString();
\r
687 cスコア.譜面情報.Presound = br.ReadString();
\r
688 cスコア.譜面情報.Backgound = br.ReadString();
\r
689 cスコア.譜面情報.レベル.Drums = br.ReadInt32();
\r
690 cスコア.譜面情報.レベル.Guitar = br.ReadInt32();
\r
691 cスコア.譜面情報.レベル.Bass = br.ReadInt32();
\r
692 cスコア.譜面情報.最大ランク.Drums = br.ReadInt32();
\r
693 cスコア.譜面情報.最大ランク.Guitar = br.ReadInt32();
\r
694 cスコア.譜面情報.最大ランク.Bass = br.ReadInt32();
\r
695 cスコア.譜面情報.最大スキル.Drums = br.ReadDouble();
\r
696 cスコア.譜面情報.最大スキル.Guitar = br.ReadDouble();
\r
697 cスコア.譜面情報.最大スキル.Bass = br.ReadDouble();
\r
698 cスコア.譜面情報.フルコンボ.Drums = br.ReadBoolean();
\r
699 cスコア.譜面情報.フルコンボ.Guitar = br.ReadBoolean();
\r
700 cスコア.譜面情報.フルコンボ.Bass = br.ReadBoolean();
\r
701 cスコア.譜面情報.演奏回数.Drums = br.ReadInt32();
\r
702 cスコア.譜面情報.演奏回数.Guitar = br.ReadInt32();
\r
703 cスコア.譜面情報.演奏回数.Bass = br.ReadInt32();
\r
704 cスコア.譜面情報.演奏履歴.行1 = br.ReadString();
\r
705 cスコア.譜面情報.演奏履歴.行2 = br.ReadString();
\r
706 cスコア.譜面情報.演奏履歴.行3 = br.ReadString();
\r
707 cスコア.譜面情報.演奏履歴.行4 = br.ReadString();
\r
708 cスコア.譜面情報.演奏履歴.行5 = br.ReadString();
\r
709 cスコア.譜面情報.レベルを非表示にする = br.ReadBoolean();
\r
710 cスコア.譜面情報.曲種別 = (CDTX.E種別) br.ReadInt32();
\r
711 // cスコア.譜面情報.bpm = br.ReadDouble();
\r
713 //Debug.WriteLine( "songs.db: " + cスコア.ファイル情報.ファイルの絶対パス );
\r
716 //-----------------
\r
718 #region [ SongsDBになかった曲をファイルから読み込んで反映する ]
\r
719 //-----------------
\r
720 public void tSongsDBになかった曲をファイルから読み込んで反映する()
\r
722 this.nファイルから反映できたスコア数 = 0;
\r
723 this.tSongsDBになかった曲をファイルから読み込んで反映する( this.list曲ルート );
\r
725 private void tSongsDBになかった曲をファイルから読み込んで反映する( List<C曲リストノード> ノードリスト )
\r
727 foreach( C曲リストノード c曲リストノード in ノードリスト )
\r
729 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
731 autoReset.WaitOne();
\r
734 if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )
\r
736 this.tSongsDBになかった曲をファイルから読み込んで反映する( c曲リストノード.list子リスト );
\r
738 else if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )
\r
739 || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
\r
741 for( int i = 0; i < 5; i++ )
\r
743 if( ( c曲リストノード.arスコア[ i ] != null ) && !c曲リストノード.arスコア[ i ].bSongDBにキャッシュがあった )
\r
745 #region [ DTX ファイルのヘッダだけ読み込み、Cスコア.譜面情報 を設定する ]
\r
746 //-----------------
\r
747 string path = c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス;
\r
748 if( File.Exists( path ) )
\r
752 CDTX cdtx = new CDTX( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス, true );
\r
753 c曲リストノード.arスコア[ i ].譜面情報.タイトル = cdtx.TITLE;
\r
754 c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 = cdtx.ARTIST;
\r
755 c曲リストノード.arスコア[ i ].譜面情報.コメント = cdtx.COMMENT;
\r
756 c曲リストノード.arスコア[ i ].譜面情報.ジャンル = cdtx.GENRE;
\r
757 c曲リストノード.arスコア[ i ].譜面情報.Preimage = cdtx.PREIMAGE;
\r
758 c曲リストノード.arスコア[ i ].譜面情報.Premovie = cdtx.PREMOVIE;
\r
759 c曲リストノード.arスコア[ i ].譜面情報.Presound = cdtx.PREVIEW;
\r
760 c曲リストノード.arスコア[ i ].譜面情報.Backgound = ( ( cdtx.BACKGROUND != null ) && ( cdtx.BACKGROUND.Length > 0 ) ) ? cdtx.BACKGROUND : cdtx.BACKGROUND_GR;
\r
761 c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums = cdtx.LEVEL.Drums;
\r
762 c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar = cdtx.LEVEL.Guitar;
\r
763 c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass = cdtx.LEVEL.Bass;
\r
764 c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする = cdtx.HIDDENLEVEL;
\r
765 c曲リストノード.arスコア[ i ].譜面情報.曲種別 = cdtx.e種別;
\r
766 // c曲リストノード.arスコア[ i ].譜面情報.bpm = cdtx.BPM;
\r
767 this.nファイルから反映できたスコア数++;
\r
769 //Debug.WriteLine( "★" + this.nファイルから反映できたスコア数 + " " + c曲リストノード.arスコア[ i ].譜面情報.タイトル );
\r
770 #region [ 曲検索ログ出力 ]
\r
771 //-----------------
\r
772 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
774 StringBuilder sb = new StringBuilder( 0x400 );
\r
775 sb.Append( string.Format( "曲データファイルから譜面情報を転記しました。({0})", path ) );
\r
776 sb.Append( "(title=" + c曲リストノード.arスコア[ i ].譜面情報.タイトル );
\r
777 sb.Append( ", artist=" + c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 );
\r
778 sb.Append( ", comment=" + c曲リストノード.arスコア[ i ].譜面情報.コメント );
\r
779 sb.Append( ", genre=" + c曲リストノード.arスコア[ i ].譜面情報.ジャンル );
\r
780 sb.Append( ", preimage=" + c曲リストノード.arスコア[ i ].譜面情報.Preimage );
\r
781 sb.Append( ", premovie=" + c曲リストノード.arスコア[ i ].譜面情報.Premovie );
\r
782 sb.Append( ", presound=" + c曲リストノード.arスコア[ i ].譜面情報.Presound );
\r
783 sb.Append( ", background=" + c曲リストノード.arスコア[ i ].譜面情報.Backgound );
\r
784 sb.Append( ", lvDr=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums );
\r
785 sb.Append( ", lvGt=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar );
\r
786 sb.Append( ", lvBs=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass );
\r
787 sb.Append( ", lvHide=" + c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする );
\r
788 sb.Append( ", type=" + c曲リストノード.arスコア[ i ].譜面情報.曲種別 );
\r
789 // builder.Append( ", bpm=" + c曲リストノード.arスコア[ i ].譜面情報.bpm );
\r
790 Trace.TraceInformation( sb.ToString() );
\r
792 //-----------------
\r
795 catch( Exception exception )
\r
797 Trace.TraceError( exception.Message );
\r
798 c曲リストノード.arスコア[ i ] = null;
\r
801 Trace.TraceError( "曲データファイルの読み込みに失敗しました。({0})", path );
\r
804 //-----------------
\r
807 #region [ 対応する .score.ini が存在していれば読み込み、Cスコア.譜面情報 に追加設定する ]
\r
808 //-----------------
\r
809 this.tScoreIniを読み込んで譜面情報を設定する( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス + ".score.ini", ref c曲リストノード.arスコア[ i ] );
\r
810 //-----------------
\r
817 //-----------------
\r
819 #region [ 曲リストへ後処理を適用する ]
\r
820 //-----------------
\r
821 public void t曲リストへ後処理を適用する()
\r
823 this.t曲リストへ後処理を適用する( this.list曲ルート );
\r
825 private void t曲リストへ後処理を適用する( List<C曲リストノード> ノードリスト )
\r
827 #region [ リストに1つ以上の曲があるなら RANDOM BOX を入れる ]
\r
828 //-----------------------------
\r
829 if( ノードリスト.Count > 0 )
\r
831 C曲リストノード itemRandom = new C曲リストノード();
\r
832 itemRandom.eノード種別 = C曲リストノード.Eノード種別.RANDOM;
\r
833 itemRandom.strタイトル = "< RANDOM SELECT >";
\r
834 itemRandom.nスコア数 = 5;
\r
835 itemRandom.r親ノード = ノードリスト[ 0 ].r親ノード;
\r
836 for( int i = 0; i < 5; i++ )
\r
838 itemRandom.arスコア[ i ] = new Cスコア();
\r
839 itemRandom.arスコア[ i ].譜面情報.タイトル = string.Format( "< RANDOM SELECT Lv.{0} >", i + 1 );
\r
840 itemRandom.arスコア[i].譜面情報.コメント =
\r
841 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?
\r
842 string.Format("難易度レベル {0} 付近の曲をランダムに選択します。難易度レベルを持たない曲も選択候補となります。", i + 1) :
\r
843 string.Format("Random select from the songs which has the level about L{0}. Non-leveled songs may also selected.", i + 1);
\r
844 itemRandom.ar難易度ラベル[ i ] = string.Format( "L{0}", i + 1 );
\r
846 ノードリスト.Add( itemRandom );
\r
849 //-----------------------------
\r
850 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
852 StringBuilder sb = new StringBuilder( 0x100 );
\r
853 sb.Append( string.Format( "nID#{0:D3}", itemRandom.nID ) );
\r
854 if( itemRandom.r親ノード != null )
\r
856 sb.Append( string.Format( "(in#{0:D3}):", itemRandom.r親ノード.nID ) );
\r
860 sb.Append( "(onRoot):" );
\r
862 sb.Append( " RANDOM" );
\r
863 Trace.TraceInformation( sb.ToString() );
\r
865 //-----------------------------
\r
868 //-----------------------------
\r
872 foreach( C曲リストノード c曲リストノード in ノードリスト )
\r
874 if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
876 autoReset.WaitOne();
\r
879 #region [ BOXノードなら子リストに <<BACK を入れ、子リストに後処理を適用する ]
\r
880 //-----------------------------
\r
881 if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )
\r
883 C曲リストノード itemBack = new C曲リストノード();
\r
884 itemBack.eノード種別 = C曲リストノード.Eノード種別.BACKBOX;
\r
885 itemBack.strタイトル = "<< BACK";
\r
886 itemBack.nスコア数 = 1;
\r
887 itemBack.r親ノード = c曲リストノード;
\r
888 itemBack.arスコア[ 0 ] = new Cスコア();
\r
889 itemBack.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = "";
\r
890 itemBack.arスコア[ 0 ].譜面情報.タイトル = itemBack.strタイトル;
\r
891 itemBack.arスコア[ 0 ].譜面情報.コメント =
\r
892 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?
\r
894 "Exit from the BOX.";
\r
895 c曲リストノード.list子リスト.Insert( 0, itemBack );
\r
898 //-----------------------------
\r
899 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
901 StringBuilder sb = new StringBuilder( 0x100 );
\r
902 sb.Append( string.Format( "nID#{0:D3}", itemBack.nID ) );
\r
903 if( itemBack.r親ノード != null )
\r
905 sb.Append( string.Format( "(in#{0:D3}):", itemBack.r親ノード.nID ) );
\r
909 sb.Append( "(onRoot):" );
\r
911 sb.Append( " BACKBOX" );
\r
912 Trace.TraceInformation( sb.ToString() );
\r
914 //-----------------------------
\r
917 this.t曲リストへ後処理を適用する( c曲リストノード.list子リスト );
\r
920 //-----------------------------
\r
923 #region [ ノードにタイトルがないなら、最初に見つけたスコアのタイトルを設定する ]
\r
924 //-----------------------------
\r
925 if( string.IsNullOrEmpty( c曲リストノード.strタイトル ) )
\r
927 for( int j = 0; j < 5; j++ )
\r
929 if( ( c曲リストノード.arスコア[ j ] != null ) && !string.IsNullOrEmpty( c曲リストノード.arスコア[ j ].譜面情報.タイトル ) )
\r
931 c曲リストノード.strタイトル = c曲リストノード.arスコア[ j ].譜面情報.タイトル;
\r
933 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )
\r
934 Trace.TraceInformation( "タイトルを設定しました。(nID#{0:D3}, title={1})", c曲リストノード.nID, c曲リストノード.strタイトル );
\r
940 //-----------------------------
\r
944 #region [ ノードをソートする ]
\r
945 //-----------------------------
\r
946 this.t曲リストのソート1_絶対パス順( ノードリスト );
\r
947 //-----------------------------
\r
950 //-----------------
\r
952 #region [ スコアキャッシュをSongsDBに出力する ]
\r
953 //-----------------
\r
954 public void tスコアキャッシュをSongsDBに出力する( string SongsDBファイル名 )
\r
956 this.nSongsDBへ出力できたスコア数 = 0;
\r
959 BinaryWriter bw = new BinaryWriter( new FileStream( SongsDBファイル名, FileMode.Create, FileAccess.Write ) );
\r
960 bw.Write( SONGSDB_VERSION );
\r
961 this.tSongsDBにリストを1つ出力する( bw, this.list曲ルート );
\r
966 Trace.TraceError( "songs.dbの出力に失敗しました。" );
\r
969 private void tSongsDBにノードを1つ出力する( BinaryWriter bw, C曲リストノード node )
\r
971 for( int i = 0; i < 5; i++ )
\r
973 // ここではsuspendに応じないようにしておく(深い意味はない。ファイルの書き込みオープン状態を長時間維持したくないだけ)
\r
974 //if ( this.bIsSuspending ) // #27060 中断要求があったら、解除要求が来るまで待機
\r
976 // autoReset.WaitOne();
\r
979 if( node.arスコア[ i ] != null )
\r
981 bw.Write( node.arスコア[ i ].ファイル情報.ファイルの絶対パス );
\r
982 bw.Write( node.arスコア[ i ].ファイル情報.フォルダの絶対パス );
\r
983 bw.Write( node.arスコア[ i ].ファイル情報.最終更新日時.Ticks );
\r
984 bw.Write( node.arスコア[ i ].ファイル情報.ファイルサイズ );
\r
985 bw.Write( node.arスコア[ i ].ScoreIni情報.最終更新日時.Ticks );
\r
986 bw.Write( node.arスコア[ i ].ScoreIni情報.ファイルサイズ );
\r
987 bw.Write( node.arスコア[ i ].譜面情報.タイトル );
\r
988 bw.Write( node.arスコア[ i ].譜面情報.アーティスト名 );
\r
989 bw.Write( node.arスコア[ i ].譜面情報.コメント );
\r
990 bw.Write( node.arスコア[ i ].譜面情報.ジャンル );
\r
991 bw.Write( node.arスコア[ i ].譜面情報.Preimage );
\r
992 bw.Write( node.arスコア[ i ].譜面情報.Premovie );
\r
993 bw.Write( node.arスコア[ i ].譜面情報.Presound );
\r
994 bw.Write( node.arスコア[ i ].譜面情報.Backgound );
\r
995 bw.Write( node.arスコア[ i ].譜面情報.レベル.Drums );
\r
996 bw.Write( node.arスコア[ i ].譜面情報.レベル.Guitar );
\r
997 bw.Write( node.arスコア[ i ].譜面情報.レベル.Bass );
\r
998 bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Drums );
\r
999 bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Guitar );
\r
1000 bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Bass );
\r
1001 bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Drums );
\r
1002 bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Guitar );
\r
1003 bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Bass );
\r
1004 bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Drums );
\r
1005 bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Guitar );
\r
1006 bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Bass );
\r
1007 bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Drums );
\r
1008 bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Guitar );
\r
1009 bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Bass );
\r
1010 bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行1 );
\r
1011 bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行2 );
\r
1012 bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行3 );
\r
1013 bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行4 );
\r
1014 bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行5 );
\r
1015 bw.Write( node.arスコア[ i ].譜面情報.レベルを非表示にする );
\r
1016 bw.Write( (int) node.arスコア[ i ].譜面情報.曲種別 );
\r
1017 // bw.Write( node.arスコア[ i ].譜面情報.bpm );
\r
1018 this.nSongsDBへ出力できたスコア数++;
\r
1022 private void tSongsDBにリストを1つ出力する( BinaryWriter bw, List<C曲リストノード> list )
\r
1024 foreach( C曲リストノード c曲リストノード in list )
\r
1026 if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )
\r
1027 || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )
\r
1029 this.tSongsDBにノードを1つ出力する( bw, c曲リストノード );
\r
1031 if( c曲リストノード.list子リスト != null )
\r
1033 this.tSongsDBにリストを1つ出力する( bw, c曲リストノード.list子リスト );
\r
1037 //-----------------
\r
1040 #region [ 曲リストソート ]
\r
1041 //-----------------
\r
1042 public void t曲リストのソート1_絶対パス順( List<C曲リストノード> ノードリスト )
\r
1044 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1051 int num = this.t比較0_共通( n1, n2 );
\r
1056 if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1058 return n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1062 if( string.IsNullOrEmpty( n1.pathSetDefの絶対パス ) )
\r
1064 for( int i = 0; i < 5; i++ )
\r
1066 if( n1.arスコア[ i ] != null )
\r
1068 str = n1.arスコア[ i ].ファイル情報.ファイルの絶対パス;
\r
1079 str = n1.pathSetDefの絶対パス + n1.SetDefのブロック番号.ToString( "00" );
\r
1082 if( string.IsNullOrEmpty( n2.pathSetDefの絶対パス ) )
\r
1084 for( int j = 0; j < 5; j++ )
\r
1086 if( n2.arスコア[ j ] != null )
\r
1088 strB = n2.arスコア[ j ].ファイル情報.ファイルの絶対パス;
\r
1089 if( strB == null )
\r
1099 strB = n2.pathSetDefの絶対パス + n2.SetDefのブロック番号.ToString( "00" );
\r
1101 return str.CompareTo( strB );
\r
1103 foreach( C曲リストノード c曲リストノード in ノードリスト )
\r
1105 if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )
\r
1107 this.t曲リストのソート1_絶対パス順( c曲リストノード.list子リスト );
\r
1111 public void t曲リストのソート2_タイトル順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1113 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1119 int num = this.t比較0_共通( n1, n2 );
\r
1122 return order * num;
\r
1124 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1126 // foreach( C曲リストノード c曲リストノード in ノードリスト )
\r
1128 // if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )
\r
1130 // this.t曲リストのソート2_タイトル順( c曲リストノード.list子リスト, part, order );
\r
1137 /// <param name="ノードリスト"></param>
\r
1138 /// <param name="part"></param>
\r
1139 /// <param name="order">1=Ascend -1=Descend</param>
\r
1140 public void t曲リストのソート3_演奏回数の多い順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1143 int nL12345 = (int) p[ 0 ];
\r
1144 if ( part != E楽器パート.UNKNOWN )
\r
1146 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1153 int num = this.t比較0_共通( n1, n2 );
\r
1156 return order * num;
\r
1158 if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1160 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1163 int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;
\r
1164 // for( int i = 0; i < 5; i++ )
\r
1166 if( n1.arスコア[ nL12345 ] != null )
\r
1168 nSumPlayCountN1 += n1.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];
\r
1170 if( n2.arスコア[ nL12345 ] != null )
\r
1172 nSumPlayCountN2 += n2.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];
\r
1175 num = nSumPlayCountN2 - nSumPlayCountN1;
\r
1178 return order * num;
\r
1180 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1182 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1184 int nSumPlayCountN1 = 0;
\r
1185 // for ( int i = 0; i < 5; i++ )
\r
1187 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1189 nSumPlayCountN1 += c曲リストノード.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];
\r
1192 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );
\r
1195 // foreach( C曲リストノード c曲リストノード in ノードリスト )
\r
1197 // if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )
\r
1199 // this.t曲リストのソート3_演奏回数の多い順( c曲リストノード.list子リスト, part );
\r
1204 public void t曲リストのソート4_LEVEL順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1207 int nL12345 = (int)p[ 0 ];
\r
1208 if ( part != E楽器パート.UNKNOWN )
\r
1210 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1217 int num = this.t比較0_共通( n1, n2 );
\r
1220 return order * num;
\r
1222 if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1224 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1227 int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;
\r
1228 if ( n1.arスコア[ nL12345 ] != null )
\r
1230 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];
\r
1232 if ( n2.arスコア[ nL12345 ] != null )
\r
1234 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];
\r
1236 num = nSumPlayCountN2 - nSumPlayCountN1;
\r
1239 return order * num;
\r
1241 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1243 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1245 int nSumPlayCountN1 = 0;
\r
1246 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1248 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];
\r
1250 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );
\r
1254 public void t曲リストのソート5_BestRank順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1257 int nL12345 = (int) p[ 0 ];
\r
1258 if ( part != E楽器パート.UNKNOWN )
\r
1260 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1267 int num = this.t比較0_共通( n1, n2 );
\r
1270 return order * num;
\r
1272 if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1274 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1277 int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;
\r
1278 bool isFullCombo1 = false, isFullCombo2 = false;
\r
1279 if ( n1.arスコア[ nL12345 ] != null )
\r
1281 isFullCombo1 = n1.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];
\r
1282 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];
\r
1284 if ( n2.arスコア[ nL12345 ] != null )
\r
1286 isFullCombo2 = n2.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];
\r
1287 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];
\r
1289 if ( isFullCombo1 ^ isFullCombo2 )
\r
1291 if ( isFullCombo1 ) return order; else return -order;
\r
1293 num = nSumPlayCountN2 - nSumPlayCountN1;
\r
1296 return order * num;
\r
1298 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1300 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1302 int nSumPlayCountN1 = 0;
\r
1303 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1305 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];
\r
1307 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );
\r
1311 public void t曲リストのソート6_SkillPoint順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1314 int nL12345 = (int) p[ 0 ];
\r
1315 if ( part != E楽器パート.UNKNOWN )
\r
1317 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1324 int num = this.t比較0_共通( n1, n2 );
\r
1327 return order * num;
\r
1329 if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1331 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1334 double nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;
\r
1335 if ( n1.arスコア[ nL12345 ] != null )
\r
1337 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];
\r
1339 if ( n2.arスコア[ nL12345 ] != null )
\r
1341 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];
\r
1343 double d = nSumPlayCountN2 - nSumPlayCountN1;
\r
1346 return order * System.Math.Sign(d);
\r
1348 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1350 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1352 double nSumPlayCountN1 = 0;
\r
1353 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1355 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];
\r
1357 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );
\r
1361 public void t曲リストのソート7_更新日時順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1363 int nL12345 = (int) p[ 0 ];
\r
1364 if ( part != E楽器パート.UNKNOWN )
\r
1366 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1373 int num = this.t比較0_共通( n1, n2 );
\r
1376 return order * num;
\r
1378 if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1380 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1383 DateTime nSumPlayCountN1 = DateTime.Parse("0001/01/01 12:00:01.000");
\r
1384 DateTime nSumPlayCountN2 = DateTime.Parse("0001/01/01 12:00:01.000");
\r
1385 if ( n1.arスコア[ nL12345 ] != null )
\r
1387 nSumPlayCountN1 = n1.arスコア[ nL12345 ].ファイル情報.最終更新日時;
\r
1389 if ( n2.arスコア[ nL12345 ] != null )
\r
1391 nSumPlayCountN2 = n2.arスコア[ nL12345 ].ファイル情報.最終更新日時;
\r
1393 int d = nSumPlayCountN1.CompareTo(nSumPlayCountN2);
\r
1396 return order * System.Math.Sign( d );
\r
1398 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1400 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1402 DateTime nSumPlayCountN1 = DateTime.Parse( "0001/01/01 12:00:01.000" );
\r
1403 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1405 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].ファイル情報.最終更新日時;
\r
1407 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );
\r
1411 public void t曲リストのソート8_アーティスト名順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1413 int nL12345 = (int) p[ 0 ];
\r
1414 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1420 int num = this.t比較0_共通( n1, n2 );
\r
1423 return order * System.Math.Sign( num );
\r
1425 string strAuthorN1 = "";
\r
1426 string strAuthorN2 = "";
\r
1427 if (n1.arスコア[ nL12345 ] != null ) {
\r
1428 strAuthorN1 = n1.arスコア[ nL12345 ].譜面情報.アーティスト名;
\r
1430 if ( n2.arスコア[ nL12345 ] != null )
\r
1432 strAuthorN2 = n2.arスコア[ nL12345 ].譜面情報.アーティスト名;
\r
1435 return order * strAuthorN1.CompareTo( strAuthorN2 );
\r
1437 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1440 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1442 s = c曲リストノード.arスコア[ nL12345 ].譜面情報.アーティスト名;
\r
1444 Debug.WriteLine( s + ":" + c曲リストノード.strタイトル );
\r
1448 public void t曲リストのソート9_BPM順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )
\r
1451 int nL12345 = (int) p[ 0 ];
\r
1452 if ( part != E楽器パート.UNKNOWN )
\r
1454 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )
\r
1461 int num = this.t比較0_共通( n1, n2 );
\r
1464 return order * num;
\r
1466 if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1468 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );
\r
1471 double dBPMn1 = 0.0, dBPMn2 = 0.0;
\r
1472 if ( n1.arスコア[ nL12345 ] != null )
\r
1474 dBPMn1 = n1.arスコア[ nL12345 ].譜面情報.bpm;
\r
1476 if ( n2.arスコア[ nL12345 ] != null )
\r
1478 dBPMn2 = n2.arスコア[ nL12345 ].譜面情報.bpm;
\r
1480 double d = dBPMn1- dBPMn2;
\r
1483 return order * System.Math.Sign( d );
\r
1485 return order * n1.strタイトル.CompareTo( n2.strタイトル );
\r
1487 foreach ( C曲リストノード c曲リストノード in ノードリスト )
\r
1490 if ( c曲リストノード.arスコア[ nL12345 ] != null )
\r
1492 dBPM = c曲リストノード.arスコア[ nL12345 ].譜面情報.bpm;
\r
1494 Debug.WriteLine( dBPM + ":" + c曲リストノード.strタイトル );
\r
1499 //-----------------
\r
1501 #region [ .score.ini を読み込んで Cスコア.譜面情報に設定する ]
\r
1502 //-----------------
\r
1503 public void tScoreIniを読み込んで譜面情報を設定する( string strScoreIniファイルパス, ref Cスコア score )
\r
1505 if( !File.Exists( strScoreIniファイルパス ) )
\r
1510 var ini = new CScoreIni( strScoreIniファイルパス );
\r
1511 ini.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();
\r
1513 for( int n楽器番号 = 0; n楽器番号 < 3; n楽器番号++ )
\r
1515 int n = ( n楽器番号 * 2 ) + 1; // n = 0~5
\r
1517 #region socre.譜面情報.最大ランク[ n楽器番号 ] = ...
\r
1518 //-----------------
\r
1519 if( ini.stセクション[ n ].b演奏にMIDI入力を使用した ||
\r
1520 ini.stセクション[ n ].b演奏にキーボードを使用した ||
\r
1521 ini.stセクション[ n ].b演奏にジョイパッドを使用した ||
\r
1522 ini.stセクション[ n ].b演奏にマウスを使用した )
\r
1524 // (A) 全オートじゃないようなので、演奏結果情報を有効としてランクを算出する。
\r
1526 score.譜面情報.最大ランク[ n楽器番号 ] =
\r
1527 CScoreIni.tランク値を計算して返す(
\r
1528 ini.stセクション[ n ].n全チップ数,
\r
1529 ini.stセクション[ n ].nPerfect数,
\r
1530 ini.stセクション[ n ].nGreat数,
\r
1531 ini.stセクション[ n ].nGood数,
\r
1532 ini.stセクション[ n ].nPoor数,
\r
1533 ini.stセクション[ n ].nMiss数 );
\r
1537 // (B) 全オートらしいので、ランクは無効とする。
\r
1539 score.譜面情報.最大ランク[ n楽器番号 ] = (int) CScoreIni.ERANK.UNKNOWN;
\r
1541 //-----------------
\r
1543 score.譜面情報.最大スキル[ n楽器番号 ] = ini.stセクション[ n ].db演奏型スキル値;
\r
1544 score.譜面情報.フルコンボ[ n楽器番号 ] = ini.stセクション[ n ].bフルコンボである;
\r
1546 score.譜面情報.演奏回数.Drums = ini.stファイル.PlayCountDrums;
\r
1547 score.譜面情報.演奏回数.Guitar = ini.stファイル.PlayCountGuitar;
\r
1548 score.譜面情報.演奏回数.Bass = ini.stファイル.PlayCountBass;
\r
1549 for( int i = 0; i < 5; i++ )
\r
1550 score.譜面情報.演奏履歴[ i ] = ini.stファイル.History[ i ];
\r
1554 Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。[{0}]", strScoreIniファイルパス );
\r
1557 //-----------------
\r
1563 #region [ private ]
\r
1564 //-----------------
\r
1565 private const string SONGSDB_VERSION = "SongsDB2";
\r
1567 private int t比較0_共通( C曲リストノード n1, C曲リストノード n2 )
\r
1569 if( n1.eノード種別 == C曲リストノード.Eノード種別.BACKBOX )
\r
1573 if( n2.eノード種別 == C曲リストノード.Eノード種別.BACKBOX )
\r
1577 if( n1.eノード種別 == C曲リストノード.Eノード種別.RANDOM )
\r
1581 if( n2.eノード種別 == C曲リストノード.Eノード種別.RANDOM )
\r
1585 if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 != C曲リストノード.Eノード種別.BOX ) )
\r
1589 if( ( n1.eノード種別 != C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )
\r
1595 //-----------------
\r