OSDN Git Service

d278dd51e3146a1e9b68070868c57456b2bf8551
[dtxmania/dtxmania.git] / DTXManiaプロジェクト / コード / スコア、曲 / CSong管理.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Globalization;\r
4 using System.Text;\r
5 using System.Diagnostics;\r
6 using System.IO;\r
7 using System.Drawing;\r
8 using System.Threading;\r
9 \r
10 namespace DTXMania\r
11 {\r
12         [Serializable]\r
13         internal class CSongs管理\r
14         {\r
15                 // プロパティ\r
16 \r
17                 public int nSongsDBから取得できたスコア数\r
18                 {\r
19                         get; \r
20                         set; \r
21                 }\r
22                 public int nSongsDBへ出力できたスコア数\r
23                 {\r
24                         get;\r
25                         set;\r
26                 }\r
27                 public int nスコアキャッシュから反映できたスコア数 \r
28                 {\r
29                         get;\r
30                         set; \r
31                 }\r
32                 public int nファイルから反映できたスコア数\r
33                 {\r
34                         get;\r
35                         set;\r
36                 }\r
37                 public int n検索されたスコア数 \r
38                 { \r
39                         get;\r
40                         set;\r
41                 }\r
42                 public int n検索された曲ノード数\r
43                 {\r
44                         get; \r
45                         set;\r
46                 }\r
47                 [NonSerialized]\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
52                         get;\r
53                         set;\r
54                 }\r
55                 public bool bIsSlowdown                                                         // #PREMOVIE再生時に曲検索を遅くする\r
56                 {\r
57                         get;\r
58                         set;\r
59                 }\r
60                 [NonSerialized]\r
61                 private AutoResetEvent autoReset;\r
62                 public AutoResetEvent AutoReset\r
63                 {\r
64                         get\r
65                         {\r
66                                 return autoReset;\r
67                         }\r
68                         private set\r
69                         {\r
70                                 autoReset = value;\r
71                         }\r
72                 }\r
73 \r
74                 private int searchCount;                                                        // #PREMOVIE中は検索n回実行したら少しスリープする\r
75 \r
76                 // コンストラクタ\r
77 \r
78                 public CSongs管理()\r
79                 {\r
80                         this.listSongsDB = new List<Cスコア>();\r
81                         this.list曲ルート = new List<C曲リストノード>();\r
82                         this.n検索された曲ノード数 = 0;\r
83                         this.n検索されたスコア数 = 0;\r
84                         this.bIsSuspending = false;                                             // #27060\r
85                         this.autoReset = new AutoResetEvent( true );    // #27060\r
86                         this.searchCount = 0;\r
87                 }\r
88 \r
89 \r
90                 // メソッド\r
91 \r
92                 #region [ SongsDB(songs.db) を読み込む ]\r
93                 //-----------------\r
94                 public void tSongsDBを読み込む( string SongsDBファイル名 )\r
95                 {\r
96                         this.nSongsDBから取得できたスコア数 = 0;\r
97                         if( File.Exists( SongsDBファイル名 ) )\r
98                         {\r
99                                 BinaryReader br = null;\r
100                                 try\r
101                                 {\r
102                                         br = new BinaryReader( File.OpenRead( SongsDBファイル名 ) );\r
103                                         if ( !br.ReadString().Equals( SONGSDB_VERSION ) )\r
104                                         {\r
105                                                 throw new InvalidDataException( "ヘッダが異なります。" );\r
106                                         }\r
107                                         this.listSongsDB = new List<Cスコア>();\r
108 \r
109                                         while( true )\r
110                                         {\r
111                                                 try\r
112                                                 {\r
113                                                         Cスコア item = this.tSongsDBからスコアを1つ読み込む( br );\r
114                                                         this.listSongsDB.Add( item );\r
115                                                         this.nSongsDBから取得できたスコア数++;\r
116                                                 }\r
117                                                 catch( EndOfStreamException )\r
118                                                 {\r
119                                                         break;\r
120                                                 }\r
121                                         }\r
122                                 }\r
123                                 finally\r
124                                 {\r
125                                         if( br != null )\r
126                                                 br.Close();\r
127                                 }\r
128                         }\r
129                 }\r
130                 //-----------------\r
131                 #endregion\r
132 \r
133                 #region [ 曲を検索してリストを作成する ]\r
134                 //-----------------\r
135                 public void t曲を検索してリストを作成する( string str基点フォルダ, bool b子BOXへ再帰する )\r
136                 {\r
137                         this.t曲を検索してリストを作成する( str基点フォルダ, b子BOXへ再帰する, this.list曲ルート, null );\r
138                 }\r
139                 private void t曲を検索してリストを作成する( string str基点フォルダ, bool b子BOXへ再帰する, List<C曲リストノード> listノードリスト, C曲リストノード node親 )\r
140                 {\r
141                         if( !str基点フォルダ.EndsWith( @"\" ) )\r
142                                 str基点フォルダ = str基点フォルダ + @"\";\r
143 \r
144                         DirectoryInfo info = new DirectoryInfo( str基点フォルダ );\r
145 \r
146                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
147                                 Trace.TraceInformation( "基点フォルダ: " + str基点フォルダ );\r
148 \r
149                         #region [ a.フォルダ内に set.def が存在する場合 → set.def からノード作成]\r
150                         //-----------------------------\r
151                         string path = str基点フォルダ + "set.def";\r
152                         if( File.Exists( path ) )\r
153                         {\r
154                                 CSetDef def = new CSetDef( path );\r
155                                 new FileInfo( path );\r
156                                 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
157                                 {\r
158                                         Trace.TraceInformation( "set.def検出 : {0}", path );\r
159                                         Trace.Indent();\r
160                                 }\r
161                                 try\r
162                                 {\r
163                                         SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
164                                         for( int i = 0; i < def.blocks.Count; i++ )\r
165                                         {\r
166                                                 CSetDef.CBlock block = def.blocks[ i ];\r
167                                                 C曲リストノード item = new C曲リストノード();\r
168                                                 item.eノード種別 = C曲リストノード.Eノード種別.SCORE;\r
169                                                 item.strタイトル = block.Title;\r
170                                                 item.strジャンル = block.Genre;\r
171                                                 item.nスコア数 = 0;\r
172                                                 item.col文字色 = block.FontColor;\r
173                                                 item.SetDefのブロック番号 = i;\r
174                                                 item.pathSetDefの絶対パス = path;\r
175                                                 item.r親ノード = node親;\r
176 \r
177                                                 item.strBreadcrumbs = ( item.r親ノード == null ) ?\r
178                                                         path + i : item.r親ノード.strBreadcrumbs + " > " + path + i;\r
179 \r
180                                                 for( int j = 0; j < 5; j++ )\r
181                                                 {\r
182                                                         if( !string.IsNullOrEmpty( block.File[ j ] ) )\r
183                                                         {\r
184                                                                 string str2 = str基点フォルダ + block.File[ j ];\r
185                                                                 if( File.Exists( str2 ) )\r
186                                                                 {\r
187                                                                         item.ar難易度ラベル[ j ] = block.Label[ j ];\r
188                                                                         item.arスコア[ j ] = new Cスコア();\r
189                                                                         item.arスコア[ j ].ファイル情報.ファイルの絶対パス = str2;\r
190                                                                         item.arスコア[ j ].ファイル情報.フォルダの絶対パス = Path.GetFullPath( Path.GetDirectoryName( str2 ) ) + @"\";\r
191                                                                         FileInfo info2 = new FileInfo( str2 );\r
192                                                                         item.arスコア[ j ].ファイル情報.ファイルサイズ = info2.Length;\r
193                                                                         item.arスコア[ j ].ファイル情報.最終更新日時 = info2.LastWriteTime;\r
194                                                                         string str3 = str2 + ".score.ini";\r
195                                                                         if( File.Exists( str3 ) )\r
196                                                                         {\r
197                                                                                 FileInfo info3 = new FileInfo( str3 );\r
198                                                                                 item.arスコア[ j ].ScoreIni情報.ファイルサイズ = info3.Length;\r
199                                                                                 item.arスコア[ j ].ScoreIni情報.最終更新日時 = info3.LastWriteTime;\r
200                                                                         }\r
201                                                                         item.nスコア数++;\r
202                                                                         this.n検索されたスコア数++;\r
203                                                                 }\r
204                                                                 else\r
205                                                                 {\r
206                                                                         item.arスコア[ j ] = null;\r
207                                                                 }\r
208                                                         }\r
209                                                 }\r
210                                                 if( item.nスコア数 > 0 )\r
211                                                 {\r
212                                                         listノードリスト.Add( item );\r
213                                                         this.n検索された曲ノード数++;\r
214                                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
215                                                         {\r
216                                                                 StringBuilder builder = new StringBuilder( 0x200 );\r
217                                                                 builder.Append( string.Format( "nID#{0:D3}", item.nID ) );\r
218                                                                 if( item.r親ノード != null )\r
219                                                                 {\r
220                                                                         builder.Append( string.Format( "(in#{0:D3}):", item.r親ノード.nID ) );\r
221                                                                 }\r
222                                                                 else\r
223                                                                 {\r
224                                                                         builder.Append( "(onRoot):" );\r
225                                                                 }\r
226                                                                 if( ( item.strタイトル != null ) && ( item.strタイトル.Length > 0 ) )\r
227                                                                 {\r
228                                                                         builder.Append( " SONG, Title=" + item.strタイトル );\r
229                                                                 }\r
230                                                                 if( ( item.strジャンル != null ) && ( item.strジャンル.Length > 0 ) )\r
231                                                                 {\r
232                                                                         builder.Append( ", Genre=" + item.strジャンル );\r
233                                                                 }\r
234                                                                 if( item.col文字色 != Color.White )\r
235                                                                 {\r
236                                                                         builder.Append( ", FontColor=" + item.col文字色 );\r
237                                                                 }\r
238                                                                 Trace.TraceInformation( builder.ToString() );\r
239                                                                 Trace.Indent();\r
240                                                                 try\r
241                                                                 {\r
242                                                                         for( int k = 0; k < 5; k++ )\r
243                                                                         {\r
244                                                                                 if( item.arスコア[ k ] != null )\r
245                                                                                 {\r
246                                                                                         Cスコア cスコア = item.arスコア[ k ];\r
247                                                                                         builder.Remove( 0, builder.Length );\r
248                                                                                         builder.Append( string.Format( "ブロック{0}-{1}:", item.SetDefのブロック番号 + 1, k + 1 ) );\r
249                                                                                         builder.Append( " Label=" + item.ar難易度ラベル[ k ] );\r
250                                                                                         builder.Append( ", File=" + cスコア.ファイル情報.ファイルの絶対パス );\r
251                                                                                         builder.Append( ", Size=" + cスコア.ファイル情報.ファイルサイズ );\r
252                                                                                         builder.Append( ", LastUpdate=" + cスコア.ファイル情報.最終更新日時 );\r
253                                                                                         Trace.TraceInformation( builder.ToString() );\r
254                                                                                 }\r
255                                                                         }\r
256                                                                 }\r
257                                                                 finally\r
258                                                                 {\r
259                                                                         Trace.Unindent();\r
260                                                                 }\r
261                                                         }\r
262                                                 }\r
263                                         }\r
264                                 }\r
265                                 finally\r
266                                 {\r
267                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
268                                         {\r
269                                                 Trace.Unindent();\r
270                                         }\r
271                                 }\r
272                         }\r
273                         //-----------------------------\r
274                         #endregion\r
275 \r
276                         #region [ b.フォルダ内に set.def が存在しない場合 → 個別ファイルからノード作成 ]\r
277                         //-----------------------------\r
278                         else\r
279                         {\r
280                                 foreach( FileInfo fileinfo in info.GetFiles() )\r
281                                 {\r
282                                         SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
283                                         string strExt = fileinfo.Extension.ToLower();\r
284                                         if( ( strExt.Equals( ".dtx" ) || strExt.Equals( ".gda" ) ) || ( ( strExt.Equals( ".g2d" ) || strExt.Equals( ".bms" ) ) || strExt.Equals( ".bme" ) ) )\r
285                                         {\r
286                                                 C曲リストノード c曲リストノード = new C曲リストノード();\r
287                                                 c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.SCORE;\r
288                                                 c曲リストノード.nスコア数 = 1;\r
289                                                 c曲リストノード.r親ノード = node親;\r
290 \r
291                                                 c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
292                                                         str基点フォルダ + fileinfo.Name : c曲リストノード.r親ノード.strBreadcrumbs + " > " + str基点フォルダ + fileinfo.Name;\r
293 \r
294                                                 c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
295                                                 c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス = str基点フォルダ + fileinfo.Name;\r
296                                                 c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = str基点フォルダ;\r
297                                                 c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ = fileinfo.Length;\r
298                                                 c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 = fileinfo.LastWriteTime;\r
299                                                 string strFileNameScoreIni = c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
300                                                 if( File.Exists( strFileNameScoreIni ) )\r
301                                                 {\r
302                                                         FileInfo infoScoreIni = new FileInfo( strFileNameScoreIni );\r
303                                                         c曲リストノード.arスコア[ 0 ].ScoreIni情報.ファイルサイズ = infoScoreIni.Length;\r
304                                                         c曲リストノード.arスコア[ 0 ].ScoreIni情報.最終更新日時 = infoScoreIni.LastWriteTime;\r
305                                                 }\r
306                                                 this.n検索されたスコア数++;\r
307                                                 listノードリスト.Add( c曲リストノード );\r
308                                                 this.n検索された曲ノード数++;\r
309                                                 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
310                                                 {\r
311                                                         Trace.Indent();\r
312                                                         try\r
313                                                         {\r
314                                                                 StringBuilder sb = new StringBuilder( 0x100 );\r
315                                                                 sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
316                                                                 if( c曲リストノード.r親ノード != null )\r
317                                                                 {\r
318                                                                         sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
319                                                                 }\r
320                                                                 else\r
321                                                                 {\r
322                                                                         sb.Append( "(onRoot):" );\r
323                                                                 }\r
324                                                                 sb.Append( " SONG, File=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルの絶対パス );\r
325                                                                 sb.Append( ", Size=" + c曲リストノード.arスコア[ 0 ].ファイル情報.ファイルサイズ );\r
326                                                                 sb.Append( ", LastUpdate=" + c曲リストノード.arスコア[ 0 ].ファイル情報.最終更新日時 );\r
327                                                                 Trace.TraceInformation( sb.ToString() );\r
328                                                         }\r
329                                                         finally\r
330                                                         {\r
331                                                                 Trace.Unindent();\r
332                                                         }\r
333                                                 }\r
334                                         }\r
335                                         else if( strExt.Equals( ".mid" ) || strExt.Equals( ".smf" ))\r
336                                         {\r
337                                                 // 何もしない\r
338                                         }\r
339                                 }\r
340                         }\r
341                         //-----------------------------\r
342                         #endregion\r
343 \r
344                         foreach( DirectoryInfo infoDir in info.GetDirectories() )\r
345                         {\r
346                                 SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
347 \r
348                                 #region [ a. "dtxfiles." で始まるフォルダの場合 ]\r
349                                 //-----------------------------\r
350                                 if( infoDir.Name.ToLower().StartsWith( "dtxfiles." ) )\r
351                                 {\r
352                                         C曲リストノード c曲リストノード = new C曲リストノード();\r
353                                         c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
354                                         c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = true;\r
355                                         c曲リストノード.strタイトル = infoDir.Name.Substring( 9 );\r
356                                         c曲リストノード.nスコア数 = 1;\r
357                                         c曲リストノード.r親ノード = node親;\r
358 \r
359                                         // 一旦、上位BOXのスキン情報をコピー (後でbox.defの記載にて上書きされる場合がある)\r
360                                         c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
361                                                 "" : c曲リストノード.r親ノード.strSkinPath;\r
362 \r
363                                         c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
364                                                 c曲リストノード.strタイトル : c曲リストノード.r親ノード.strBreadcrumbs + " > " + c曲リストノード.strタイトル;\r
365 \r
366                 \r
367                                         c曲リストノード.list子リスト = new List<C曲リストノード>();\r
368                                         c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
369                                         c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";\r
370                                         c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = c曲リストノード.strタイトル;\r
371                                         c曲リストノード.arスコア[ 0 ].譜面情報.コメント =\r
372                                                 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
373                                                 "BOX に移動します。" :\r
374                                                 "Enter into the BOX.";\r
375                                         listノードリスト.Add(c曲リストノード);\r
376                                         if( File.Exists( infoDir.FullName + @"\box.def" ) )\r
377                                         {\r
378                                                 CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );\r
379                                                 if( ( boxdef.Title != null ) && ( boxdef.Title.Length > 0 ) )\r
380                                                 {\r
381                                                         c曲リストノード.strタイトル = boxdef.Title;\r
382                                                 }\r
383                                                 if( ( boxdef.Genre != null ) && ( boxdef.Genre.Length > 0 ) )\r
384                                                 {\r
385                                                         c曲リストノード.strジャンル = boxdef.Genre;\r
386                                                 }\r
387                                                 if( boxdef.Color != Color.White )\r
388                                                 {\r
389                                                         c曲リストノード.col文字色 = boxdef.Color;\r
390                                                 }\r
391                                                 if( ( boxdef.Artist != null ) && ( boxdef.Artist.Length > 0 ) )\r
392                                                 {\r
393                                                         c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;\r
394                                                 }\r
395                                                 if( ( boxdef.Comment != null ) && ( boxdef.Comment.Length > 0 ) )\r
396                                                 {\r
397                                                         c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;\r
398                                                 }\r
399                                                 if( ( boxdef.Preimage != null ) && ( boxdef.Preimage.Length > 0 ) )\r
400                                                 {\r
401                                                         c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;\r
402                                                 }\r
403                                                 if( ( boxdef.Premovie != null ) && ( boxdef.Premovie.Length > 0 ) )\r
404                                                 {\r
405                                                         c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;\r
406                                                 }\r
407                                                 if( ( boxdef.Presound != null ) && ( boxdef.Presound.Length > 0 ) )\r
408                                                 {\r
409                                                         c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;\r
410                                                 }\r
411                                                 if ( boxdef.SkinPath != null )\r
412                                                 {\r
413                                                         if ( boxdef.SkinPath == "" )\r
414                                                         {\r
415                                                                 // box.defにスキン情報が記載されていないなら、上位BOXのスキン情報をコピー\r
416                                                                 c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
417                                                                         "" : c曲リストノード.r親ノード.strSkinPath;\r
418                                                         }\r
419                                                         else\r
420                                                         {\r
421                                                                 //      box.def 記載のスキン情報を利用\r
422                                                                 c曲リストノード.strSkinPath = System.IO.Path.Combine( infoDir.FullName, boxdef.SkinPath );\r
423                                                         }\r
424                                                 }\r
425                                                 if ( boxdef.PerfectRange >= 0 )\r
426                                                 {\r
427                                                         c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;\r
428                                                 }\r
429                                                 if( boxdef.GreatRange >= 0 )\r
430                                                 {\r
431                                                         c曲リストノード.nGreat範囲ms = boxdef.GreatRange;\r
432                                                 }\r
433                                                 if( boxdef.GoodRange >= 0 )\r
434                                                 {\r
435                                                         c曲リストノード.nGood範囲ms = boxdef.GoodRange;\r
436                                                 }\r
437                                                 if( boxdef.PoorRange >= 0 )\r
438                                                 {\r
439                                                         c曲リストノード.nPoor範囲ms = boxdef.PoorRange;\r
440                                                 }\r
441                                         }\r
442                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
443                                         {\r
444                                                 Trace.Indent();\r
445                                                 try\r
446                                                 {\r
447                                                         StringBuilder sb = new StringBuilder( 0x100 );\r
448                                                         sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
449                                                         if( c曲リストノード.r親ノード != null )\r
450                                                         {\r
451                                                                 sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
452                                                         }\r
453                                                         else\r
454                                                         {\r
455                                                                 sb.Append( "(onRoot):" );\r
456                                                         }\r
457                                                         sb.Append( " BOX, Title=" + c曲リストノード.strタイトル );\r
458                                                         sb.Append( ", Folder=" + c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
459                                                         sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );\r
460                                                         sb.Append( ", SkinPath=" + c曲リストノード.strSkinPath );\r
461                                                         Trace.TraceInformation( sb.ToString() );\r
462                                                 }\r
463                                                 finally\r
464                                                 {\r
465                                                         Trace.Unindent();\r
466                                                 }\r
467                                         }\r
468                                         if( b子BOXへ再帰する )\r
469                                         {\r
470                                                 this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );\r
471                                         }\r
472                                 }\r
473                                 //-----------------------------\r
474                                 #endregion\r
475 \r
476                                 #region [ b.box.def を含むフォルダの場合  ]\r
477                                 //-----------------------------\r
478                                 else if( File.Exists( infoDir.FullName + @"\box.def" ) )\r
479                                 {\r
480                                         CBoxDef boxdef = new CBoxDef( infoDir.FullName + @"\box.def" );\r
481                                         C曲リストノード c曲リストノード = new C曲リストノード();\r
482                                         c曲リストノード.eノード種別 = C曲リストノード.Eノード種別.BOX;\r
483                                         c曲リストノード.bDTXFilesで始まるフォルダ名のBOXである = false;\r
484                                         c曲リストノード.strタイトル = boxdef.Title;\r
485                                         c曲リストノード.strジャンル = boxdef.Genre;\r
486                                         c曲リストノード.col文字色 = boxdef.Color;\r
487                                         c曲リストノード.nスコア数 = 1;\r
488                                         c曲リストノード.arスコア[ 0 ] = new Cスコア();\r
489                                         c曲リストノード.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = infoDir.FullName + @"\";\r
490                                         c曲リストノード.arスコア[ 0 ].譜面情報.タイトル = boxdef.Title;\r
491                                         c曲リストノード.arスコア[ 0 ].譜面情報.ジャンル = boxdef.Genre;\r
492                                         c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 = boxdef.Artist;\r
493                                         c曲リストノード.arスコア[ 0 ].譜面情報.コメント = boxdef.Comment;\r
494                                         c曲リストノード.arスコア[ 0 ].譜面情報.Preimage = boxdef.Preimage;\r
495                                         c曲リストノード.arスコア[ 0 ].譜面情報.Premovie = boxdef.Premovie;\r
496                                         c曲リストノード.arスコア[ 0 ].譜面情報.Presound = boxdef.Presound;\r
497                                         c曲リストノード.r親ノード = node親;\r
498 \r
499                                         if ( boxdef.SkinPath == "" )\r
500                                         {\r
501                                                 // box.defにスキン情報が記載されていないなら、上位BOXのスキン情報をコピー\r
502                                                 c曲リストノード.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
503                                                         "" : c曲リストノード.r親ノード.strSkinPath;\r
504                                         }\r
505                                         else\r
506                                         {\r
507                                                 // box.defに記載されているスキン情報をコピー\r
508                                                 c曲リストノード.strSkinPath = System.IO.Path.Combine( infoDir.FullName, boxdef.SkinPath );\r
509                                         }\r
510                                         c曲リストノード.strBreadcrumbs = ( c曲リストノード.r親ノード == null ) ?\r
511                                                 c曲リストノード.strタイトル : c曲リストノード.r親ノード.strBreadcrumbs + " > " + c曲リストノード.strタイトル;\r
512         \r
513                                         \r
514                                         c曲リストノード.list子リスト = new List<C曲リストノード>();\r
515                                         c曲リストノード.nPerfect範囲ms = boxdef.PerfectRange;\r
516                                         c曲リストノード.nGreat範囲ms = boxdef.GreatRange;\r
517                                         c曲リストノード.nGood範囲ms = boxdef.GoodRange;\r
518                                         c曲リストノード.nPoor範囲ms = boxdef.PoorRange;\r
519                                         listノードリスト.Add( c曲リストノード );\r
520                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
521                                         {\r
522                                                 Trace.TraceInformation( "box.def検出 : {0}", infoDir.FullName + @"\box.def" );\r
523                                                 Trace.Indent();\r
524                                                 try\r
525                                                 {\r
526                                                         StringBuilder sb = new StringBuilder( 0x400 );\r
527                                                         sb.Append( string.Format( "nID#{0:D3}", c曲リストノード.nID ) );\r
528                                                         if( c曲リストノード.r親ノード != null )\r
529                                                         {\r
530                                                                 sb.Append( string.Format( "(in#{0:D3}):", c曲リストノード.r親ノード.nID ) );\r
531                                                         }\r
532                                                         else\r
533                                                         {\r
534                                                                 sb.Append( "(onRoot):" );\r
535                                                         }\r
536                                                         sb.Append( "BOX, Title=" + c曲リストノード.strタイトル );\r
537                                                         if( ( c曲リストノード.strジャンル != null ) && ( c曲リストノード.strジャンル.Length > 0 ) )\r
538                                                         {\r
539                                                                 sb.Append( ", Genre=" + c曲リストノード.strジャンル );\r
540                                                         }\r
541                                                         if( ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名.Length > 0 ) )\r
542                                                         {\r
543                                                                 sb.Append( ", Artist=" + c曲リストノード.arスコア[ 0 ].譜面情報.アーティスト名 );\r
544                                                         }\r
545                                                         if( ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.コメント.Length > 0 ) )\r
546                                                         {\r
547                                                                 sb.Append( ", Comment=" + c曲リストノード.arスコア[ 0 ].譜面情報.コメント );\r
548                                                         }\r
549                                                         if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Preimage.Length > 0 ) )\r
550                                                         {\r
551                                                                 sb.Append( ", Preimage=" + c曲リストノード.arスコア[ 0 ].譜面情報.Preimage );\r
552                                                         }\r
553                                                         if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Premovie.Length > 0 ) )\r
554                                                         {\r
555                                                                 sb.Append( ", Premovie=" + c曲リストノード.arスコア[ 0 ].譜面情報.Premovie );\r
556                                                         }\r
557                                                         if( ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound != null ) && ( c曲リストノード.arスコア[ 0 ].譜面情報.Presound.Length > 0 ) )\r
558                                                         {\r
559                                                                 sb.Append( ", Presound=" + c曲リストノード.arスコア[ 0 ].譜面情報.Presound );\r
560                                                         }\r
561                                                         if( c曲リストノード.col文字色 != ColorTranslator.FromHtml( "White" ) )\r
562                                                         {\r
563                                                                 sb.Append( ", FontColor=" + c曲リストノード.col文字色 );\r
564                                                         }\r
565                                                         if( c曲リストノード.nPerfect範囲ms != -1 )\r
566                                                         {\r
567                                                                 sb.Append( ", Perfect=" + c曲リストノード.nPerfect範囲ms + "ms" );\r
568                                                         }\r
569                                                         if( c曲リストノード.nGreat範囲ms != -1 )\r
570                                                         {\r
571                                                                 sb.Append( ", Great=" + c曲リストノード.nGreat範囲ms + "ms" );\r
572                                                         }\r
573                                                         if( c曲リストノード.nGood範囲ms != -1 )\r
574                                                         {\r
575                                                                 sb.Append( ", Good=" + c曲リストノード.nGood範囲ms + "ms" );\r
576                                                         }\r
577                                                         if( c曲リストノード.nPoor範囲ms != -1 )\r
578                                                         {\r
579                                                                 sb.Append( ", Poor=" + c曲リストノード.nPoor範囲ms + "ms" );\r
580                                                         }\r
581                                                         if ( ( c曲リストノード.strSkinPath != null ) && ( c曲リストノード.strSkinPath.Length > 0 ) )\r
582                                                         {\r
583                                                                 sb.Append( ", SkinPath=" + c曲リストノード.strSkinPath );\r
584                                                         }\r
585                                                         Trace.TraceInformation( sb.ToString() );\r
586                                                 }\r
587                                                 finally\r
588                                                 {\r
589                                                         Trace.Unindent();\r
590                                                 }\r
591                                         }\r
592                                         if( b子BOXへ再帰する )\r
593                                         {\r
594                                                 this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, c曲リストノード.list子リスト, c曲リストノード );\r
595                                         }\r
596                                 }\r
597                                 //-----------------------------\r
598                                 #endregion\r
599 \r
600                                 #region [ c.通常フォルダの場合 ]\r
601                                 //-----------------------------\r
602                                 else\r
603                                 {\r
604                                         this.t曲を検索してリストを作成する( infoDir.FullName + @"\", b子BOXへ再帰する, listノードリスト, node親 );\r
605                                 }\r
606                                 //-----------------------------\r
607                                 #endregion\r
608                         }\r
609                 }\r
610                 //-----------------\r
611                 #endregion\r
612                 #region [ スコアキャッシュを曲リストに反映する ]\r
613                 //-----------------\r
614                 public void tスコアキャッシュを曲リストに反映する()\r
615                 {\r
616                         this.nスコアキャッシュから反映できたスコア数 = 0;\r
617                         this.tスコアキャッシュを曲リストに反映する( this.list曲ルート );\r
618                 }\r
619                 private void tスコアキャッシュを曲リストに反映する( List<C曲リストノード> ノードリスト )\r
620                 {\r
621                         using( List<C曲リストノード>.Enumerator enumerator = ノードリスト.GetEnumerator() )\r
622                         {\r
623                                 while( enumerator.MoveNext() )\r
624                                 {\r
625                                         SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
626 \r
627                                         C曲リストノード node = enumerator.Current;\r
628                                         if( node.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
629                                         {\r
630                                                 this.tスコアキャッシュを曲リストに反映する( node.list子リスト );\r
631                                         }\r
632                                         else if( ( node.eノード種別 == C曲リストノード.Eノード種別.SCORE ) || ( node.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
633                                         {\r
634                                                 Predicate<Cスコア> match = null;\r
635                                                 for( int lv = 0; lv < 5; lv++ )\r
636                                                 {\r
637                                                         if( node.arスコア[ lv ] != null )\r
638                                                         {\r
639                                                                 if( match == null )\r
640                                                                 {\r
641                                                                         match = delegate( Cスコア sc )\r
642                                                                         {\r
643                                                                                 return\r
644                                                                                         (\r
645                                                                                         ( sc.ファイル情報.ファイルの絶対パス.Equals( node.arスコア[ lv ].ファイル情報.ファイルの絶対パス )\r
646                                                                                         && sc.ファイル情報.ファイルサイズ.Equals( node.arスコア[ lv ].ファイル情報.ファイルサイズ ) )\r
647                                                                                         && ( sc.ファイル情報.最終更新日時.Equals( node.arスコア[ lv ].ファイル情報.最終更新日時 )\r
648                                                                                         && sc.ScoreIni情報.ファイルサイズ.Equals( node.arスコア[ lv ].ScoreIni情報.ファイルサイズ ) ) )\r
649                                                                                         && sc.ScoreIni情報.最終更新日時.Equals( node.arスコア[ lv ].ScoreIni情報.最終更新日時 );\r
650                                                                         };\r
651                                                                 }\r
652                                                                 int nMatched = this.listSongsDB.FindIndex( match );\r
653                                                                 if( nMatched == -1 )\r
654                                                                 {\r
655 //Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
656                                                                         if ( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
657                                                                         {\r
658                                                                                 Trace.TraceInformation( "songs.db に存在しません。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
659                                                                         }\r
660                                                                 }\r
661                                                                 else\r
662                                                                 {\r
663                                                                         node.arスコア[ lv ].譜面情報 = this.listSongsDB[ nMatched ].譜面情報;\r
664                                                                         node.arスコア[ lv ].bSongDBにキャッシュがあった = true;\r
665                                                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
666                                                                         {\r
667                                                                                 Trace.TraceInformation( "songs.db から転記しました。({0})", node.arスコア[ lv ].ファイル情報.ファイルの絶対パス );\r
668                                                                         }\r
669                                                                         this.nスコアキャッシュから反映できたスコア数++;\r
670                                                                         if( node.arスコア[ lv ].ScoreIni情報.最終更新日時 != this.listSongsDB[ nMatched ].ScoreIni情報.最終更新日時 )\r
671                                                                         {\r
672                                                                                 string strFileNameScoreIni = node.arスコア[ lv ].ファイル情報.ファイルの絶対パス + ".score.ini";\r
673                                                                                 try\r
674                                                                                 {\r
675                                                                                         CScoreIni scoreIni = new CScoreIni( strFileNameScoreIni );\r
676                                                                                         scoreIni.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
677                                                                                         for( int i = 0; i < 3; i++ )\r
678                                                                                         {\r
679                                                                                                 int nSectionHiSkill = ( i * 2 ) + 1;\r
680                                                                                                 if(    scoreIni.stセクション[ nSectionHiSkill ].b演奏にMIDI入力を使用した\r
681                                                                                                         || scoreIni.stセクション[ nSectionHiSkill ].b演奏にキーボードを使用した\r
682                                                                                                         || scoreIni.stセクション[ nSectionHiSkill ].b演奏にジョイパッドを使用した\r
683                                                                                                         || scoreIni.stセクション[ nSectionHiSkill ].b演奏にマウスを使用した )\r
684                                                                                                 {\r
685                                                                                                         node.arスコア[ lv ].譜面情報.最大ランク[ i ] = \r
686                                                                                                                 (scoreIni.stファイル.BestRank[i] != (int)CScoreIni.ERANK.UNKNOWN)?\r
687                                                                                                                 (int)scoreIni.stファイル.BestRank[i] : CScoreIni.tランク値を計算して返す( scoreIni.stセクション[ nSectionHiSkill ] );\r
688                                                                                                 }\r
689                                                                                                 else\r
690                                                                                                 {\r
691                                                                                                         node.arスコア[ lv ].譜面情報.最大ランク[ i ] = (int)CScoreIni.ERANK.UNKNOWN;\r
692                                                                                                 }\r
693                                                                                                 node.arスコア[ lv ].譜面情報.最大スキル[ i ] = scoreIni.stセクション[ nSectionHiSkill ].db演奏型スキル値;\r
694                                                                                                 node.arスコア[ lv ].譜面情報.フルコンボ[ i ] = scoreIni.stセクション[ nSectionHiSkill ].bフルコンボである;\r
695                                                                                         }\r
696                                                                                         node.arスコア[ lv ].譜面情報.演奏回数.Drums = scoreIni.stファイル.PlayCountDrums;\r
697                                                                                         node.arスコア[ lv ].譜面情報.演奏回数.Guitar = scoreIni.stファイル.PlayCountGuitar;\r
698                                                                                         node.arスコア[ lv ].譜面情報.演奏回数.Bass = scoreIni.stファイル.PlayCountBass;\r
699                                                                                         for( int j = 0; j < 5; j++ )\r
700                                                                                         {\r
701                                                                                                 node.arスコア[ lv ].譜面情報.演奏履歴[ j ] = scoreIni.stファイル.History[ j ];\r
702                                                                                         }\r
703                                                                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
704                                                                                         {\r
705                                                                                                 Trace.TraceInformation( "演奏記録ファイルから HiSkill 情報と演奏履歴を取得しました。({0})", strFileNameScoreIni );\r
706                                                                                         }\r
707                                                                                 }\r
708                                                                                 catch\r
709                                                                                 {\r
710                                                                                         Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。({0})", strFileNameScoreIni );\r
711                                                                                 }\r
712                                                                         }\r
713                                                                 }\r
714                                                         }\r
715                                                 }\r
716                                         }\r
717                                 }\r
718                         }\r
719                 }\r
720                 private Cスコア tSongsDBからスコアを1つ読み込む( BinaryReader br )\r
721                 {\r
722                         Cスコア cスコア = new Cスコア();\r
723                         cスコア.ファイル情報.ファイルの絶対パス = br.ReadString();\r
724                         cスコア.ファイル情報.フォルダの絶対パス = br.ReadString();\r
725                         cスコア.ファイル情報.最終更新日時 = new DateTime( br.ReadInt64() );\r
726                         cスコア.ファイル情報.ファイルサイズ = br.ReadInt64();\r
727                         cスコア.ScoreIni情報.最終更新日時 = new DateTime( br.ReadInt64() );\r
728                         cスコア.ScoreIni情報.ファイルサイズ = br.ReadInt64();\r
729                         cスコア.譜面情報.タイトル = br.ReadString();\r
730                         cスコア.譜面情報.アーティスト名 = br.ReadString();\r
731                         cスコア.譜面情報.コメント = br.ReadString();\r
732                         cスコア.譜面情報.ジャンル = br.ReadString();\r
733                         cスコア.譜面情報.Preimage = br.ReadString();\r
734                         cスコア.譜面情報.Premovie = br.ReadString();\r
735                         cスコア.譜面情報.Presound = br.ReadString();\r
736                         cスコア.譜面情報.Backgound = br.ReadString();\r
737                         cスコア.譜面情報.レベル.Drums = br.ReadInt32();\r
738                         cスコア.譜面情報.レベル.Guitar = br.ReadInt32();\r
739                         cスコア.譜面情報.レベル.Bass = br.ReadInt32();\r
740                         cスコア.譜面情報.最大ランク.Drums = br.ReadInt32();\r
741                         cスコア.譜面情報.最大ランク.Guitar = br.ReadInt32();\r
742                         cスコア.譜面情報.最大ランク.Bass = br.ReadInt32();\r
743                         cスコア.譜面情報.最大スキル.Drums = br.ReadDouble();\r
744                         cスコア.譜面情報.最大スキル.Guitar = br.ReadDouble();\r
745                         cスコア.譜面情報.最大スキル.Bass = br.ReadDouble();\r
746                         cスコア.譜面情報.フルコンボ.Drums = br.ReadBoolean();\r
747                         cスコア.譜面情報.フルコンボ.Guitar = br.ReadBoolean();\r
748                         cスコア.譜面情報.フルコンボ.Bass = br.ReadBoolean();\r
749                         cスコア.譜面情報.演奏回数.Drums = br.ReadInt32();\r
750                         cスコア.譜面情報.演奏回数.Guitar = br.ReadInt32();\r
751                         cスコア.譜面情報.演奏回数.Bass = br.ReadInt32();\r
752                         cスコア.譜面情報.演奏履歴.行1 = br.ReadString();\r
753                         cスコア.譜面情報.演奏履歴.行2 = br.ReadString();\r
754                         cスコア.譜面情報.演奏履歴.行3 = br.ReadString();\r
755                         cスコア.譜面情報.演奏履歴.行4 = br.ReadString();\r
756                         cスコア.譜面情報.演奏履歴.行5 = br.ReadString();\r
757                         cスコア.譜面情報.レベルを非表示にする = br.ReadBoolean();\r
758                         cスコア.譜面情報.曲種別 = (CDTX.E種別) br.ReadInt32();\r
759                         cスコア.譜面情報.Bpm = br.ReadDouble();\r
760                         cスコア.譜面情報.Duration = br.ReadInt32();\r
761 \r
762 //Debug.WriteLine( "songs.db: " + cスコア.ファイル情報.ファイルの絶対パス );\r
763                         return cスコア;\r
764                 }\r
765                 //-----------------\r
766                 #endregion\r
767                 #region [ SongsDBになかった曲をファイルから読み込んで反映する ]\r
768                 //-----------------\r
769                 public void tSongsDBになかった曲をファイルから読み込んで反映する()\r
770                 {\r
771                         this.nファイルから反映できたスコア数 = 0;\r
772                         this.tSongsDBになかった曲をファイルから読み込んで反映する( this.list曲ルート );\r
773                 }\r
774                 private void tSongsDBになかった曲をファイルから読み込んで反映する( List<C曲リストノード> ノードリスト )\r
775                 {\r
776                         foreach( C曲リストノード c曲リストノード in ノードリスト )\r
777                         {\r
778                                 SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
779 \r
780                                 if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
781                                 {\r
782                                         this.tSongsDBになかった曲をファイルから読み込んで反映する( c曲リストノード.list子リスト );\r
783                                 }\r
784                                 else if( ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )\r
785                                           || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
786                                 {\r
787                                         for( int i = 0; i < 5; i++ )\r
788                                         {\r
789                                                 if( ( c曲リストノード.arスコア[ i ] != null ) && !c曲リストノード.arスコア[ i ].bSongDBにキャッシュがあった )\r
790                                                 {\r
791                                                         #region [ DTX ファイルのヘッダだけ読み込み、Cスコア.譜面情報 を設定する ]\r
792                                                         //-----------------\r
793                                                         string path = c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス;\r
794                                                         if( File.Exists( path ) )\r
795                                                         {\r
796                                                                 try\r
797                                                                 {\r
798                                                                         CDTX cdtx = new CDTX( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス, true );\r
799                                                                         c曲リストノード.arスコア[ i ].譜面情報.タイトル = cdtx.TITLE;\r
800                                                                         c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 = cdtx.ARTIST;\r
801                                                                         c曲リストノード.arスコア[ i ].譜面情報.コメント = cdtx.COMMENT;\r
802                                                                         c曲リストノード.arスコア[ i ].譜面情報.ジャンル = cdtx.GENRE;\r
803                                                                         c曲リストノード.arスコア[ i ].譜面情報.Preimage = cdtx.PREIMAGE;\r
804                                                                         c曲リストノード.arスコア[ i ].譜面情報.Premovie = cdtx.PREMOVIE;\r
805                                                                         c曲リストノード.arスコア[ i ].譜面情報.Presound = cdtx.PREVIEW;\r
806                                                                         c曲リストノード.arスコア[ i ].譜面情報.Backgound = ( ( cdtx.BACKGROUND != null ) && ( cdtx.BACKGROUND.Length > 0 ) ) ? cdtx.BACKGROUND : cdtx.BACKGROUND_GR;\r
807                                                                         c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums = cdtx.LEVEL.Drums;\r
808                                                                         c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar = cdtx.LEVEL.Guitar;\r
809                                                                         c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass = cdtx.LEVEL.Bass;\r
810                                                                         c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする = cdtx.HIDDENLEVEL;\r
811                                                                         c曲リストノード.arスコア[ i ].譜面情報.曲種別 = cdtx.e種別;\r
812                                                                         c曲リストノード.arスコア[ i ].譜面情報.Bpm = cdtx.BPM;\r
813                                                                         c曲リストノード.arスコア[ i ].譜面情報.Duration = 0;      //  (cdtx.listChip == null)? 0 : cdtx.listChip[ cdtx.listChip.Count - 1 ].n発声時刻ms;\r
814                                                                         this.nファイルから反映できたスコア数++;\r
815                                                                         cdtx.On非活性化();\r
816 //Debug.WriteLine( "★" + this.nファイルから反映できたスコア数 + " " + c曲リストノード.arスコア[ i ].譜面情報.タイトル );\r
817                                                                         #region [ 曲検索ログ出力 ]\r
818                                                                         //-----------------\r
819                                                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
820                                                                         {\r
821                                                                                 StringBuilder sb = new StringBuilder( 0x400 );\r
822                                                                                 sb.Append( string.Format( "曲データファイルから譜面情報を転記しました。({0})", path ) );\r
823                                                                                 sb.Append( "(title=" + c曲リストノード.arスコア[ i ].譜面情報.タイトル );\r
824                                                                                 sb.Append( ", artist=" + c曲リストノード.arスコア[ i ].譜面情報.アーティスト名 );\r
825                                                                                 sb.Append( ", comment=" + c曲リストノード.arスコア[ i ].譜面情報.コメント );\r
826                                                                                 sb.Append( ", genre=" + c曲リストノード.arスコア[ i ].譜面情報.ジャンル );\r
827                                                                                 sb.Append( ", preimage=" + c曲リストノード.arスコア[ i ].譜面情報.Preimage );\r
828                                                                                 sb.Append( ", premovie=" + c曲リストノード.arスコア[ i ].譜面情報.Premovie );\r
829                                                                                 sb.Append( ", presound=" + c曲リストノード.arスコア[ i ].譜面情報.Presound );\r
830                                                                                 sb.Append( ", background=" + c曲リストノード.arスコア[ i ].譜面情報.Backgound );\r
831                                                                                 sb.Append( ", lvDr=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Drums );\r
832                                                                                 sb.Append( ", lvGt=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Guitar );\r
833                                                                                 sb.Append( ", lvBs=" + c曲リストノード.arスコア[ i ].譜面情報.レベル.Bass );\r
834                                                                                 sb.Append( ", lvHide=" + c曲リストノード.arスコア[ i ].譜面情報.レベルを非表示にする );\r
835                                                                                 sb.Append( ", type=" + c曲リストノード.arスコア[ i ].譜面情報.曲種別 );\r
836                                                                                 sb.Append( ", bpm=" + c曲リストノード.arスコア[ i ].譜面情報.Bpm );\r
837                                                                         //      sb.Append( ", duration=" + c曲リストノード.arスコア[ i ].譜面情報.Duration );\r
838                                                                                 Trace.TraceInformation( sb.ToString() );\r
839                                                                         }\r
840                                                                         //-----------------\r
841                                                                         #endregion\r
842                                                                 }\r
843                                                                 catch( Exception exception )\r
844                                                                 {\r
845                                                                         Trace.TraceError( exception.Message );\r
846                                                                         c曲リストノード.arスコア[ i ] = null;\r
847                                                                         c曲リストノード.nスコア数--;\r
848                                                                         this.n検索されたスコア数--;\r
849                                                                         Trace.TraceError( "曲データファイルの読み込みに失敗しました。({0})", path );\r
850                                                                 }\r
851                                                         }\r
852                                                         //-----------------\r
853                                                         #endregion\r
854 \r
855                                                         #region [ 対応する .score.ini が存在していれば読み込み、Cスコア.譜面情報 に追加設定する ]\r
856                                                         //-----------------\r
857                                                         this.tScoreIniを読み込んで譜面情報を設定する( c曲リストノード.arスコア[ i ].ファイル情報.ファイルの絶対パス + ".score.ini", ref c曲リストノード.arスコア[ i ] );\r
858                                                         //-----------------\r
859                                                         #endregion\r
860                                                 }\r
861                                         }\r
862                                 }\r
863                         }\r
864                 }\r
865                 //-----------------\r
866                 #endregion\r
867                 #region [ 曲リストへ後処理を適用する ]\r
868                 //-----------------\r
869                 public void t曲リストへ後処理を適用する()\r
870                 {\r
871                         this.t曲リストへ後処理を適用する( this.list曲ルート );\r
872                 }\r
873                 private void t曲リストへ後処理を適用する( List<C曲リストノード> ノードリスト )\r
874                 {\r
875                         #region [ リストに1つ以上の曲があるなら RANDOM BOX を入れる ]\r
876                         //-----------------------------\r
877                         if( ノードリスト.Count > 0 )\r
878                         {\r
879                                 C曲リストノード itemRandom = new C曲リストノード();\r
880                                 itemRandom.eノード種別 = C曲リストノード.Eノード種別.RANDOM;\r
881                                 itemRandom.strタイトル = "< RANDOM SELECT >";\r
882                                 itemRandom.nスコア数 = 5;\r
883                                 itemRandom.r親ノード = ノードリスト[ 0 ].r親ノード;\r
884 \r
885                                 itemRandom.strBreadcrumbs = ( itemRandom.r親ノード == null ) ?\r
886                                         itemRandom.strタイトル :  itemRandom.r親ノード.strBreadcrumbs + " > " + itemRandom.strタイトル;\r
887 \r
888                                 for( int i = 0; i < 5; i++ )\r
889                                 {\r
890                                         itemRandom.arスコア[ i ] = new Cスコア();\r
891                                         itemRandom.arスコア[ i ].譜面情報.タイトル = string.Format( "< RANDOM SELECT Lv.{0} >", i + 1 );\r
892                                         itemRandom.arスコア[i].譜面情報.コメント =\r
893                                                  (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
894                                                  string.Format("難易度レベル {0} 付近の曲をランダムに選択します。難易度レベルを持たない曲も選択候補となります。", i + 1) :\r
895                                                  string.Format("Random select from the songs which has the level about L{0}. Non-leveled songs may also selected.", i + 1);\r
896                                         itemRandom.ar難易度ラベル[ i ] = string.Format( "L{0}", i + 1 );\r
897                                 }\r
898                                 ノードリスト.Add( itemRandom );\r
899 \r
900                                 #region [ ログ出力 ]\r
901                                 //-----------------------------\r
902                                 if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
903                                 {\r
904                                         StringBuilder sb = new StringBuilder( 0x100 );\r
905                                         sb.Append( string.Format( "nID#{0:D3}", itemRandom.nID ) );\r
906                                         if( itemRandom.r親ノード != null )\r
907                                         {\r
908                                                 sb.Append( string.Format( "(in#{0:D3}):", itemRandom.r親ノード.nID ) );\r
909                                         }\r
910                                         else\r
911                                         {\r
912                                                 sb.Append( "(onRoot):" );\r
913                                         }\r
914                                         sb.Append( " RANDOM" );\r
915                                         Trace.TraceInformation( sb.ToString() );\r
916                                 }\r
917                                 //-----------------------------\r
918                                 #endregion\r
919                         }\r
920                         //-----------------------------\r
921                         #endregion\r
922 \r
923                         // すべてのノードについて…\r
924                         foreach( C曲リストノード c曲リストノード in ノードリスト )\r
925                         {\r
926                                 SlowOrSuspendSearchTask();              // #27060 中断要求があったら、解除要求が来るまで待機, #PREMOVIE再生中は検索負荷を落とす\r
927 \r
928                                 #region [ BOXノードなら子リストに <<BACK を入れ、子リストに後処理を適用する ]\r
929                                 //-----------------------------\r
930                                 if( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.BOX )\r
931                                 {\r
932                                         C曲リストノード itemBack = new C曲リストノード();\r
933                                         itemBack.eノード種別 = C曲リストノード.Eノード種別.BACKBOX;\r
934                                         itemBack.strタイトル = "<< BACK";\r
935                                         itemBack.nスコア数 = 1;\r
936                                         itemBack.r親ノード = c曲リストノード;\r
937 \r
938                                         itemBack.strSkinPath = ( c曲リストノード.r親ノード == null ) ?\r
939                                                 "" : c曲リストノード.r親ノード.strSkinPath;\r
940 \r
941                                         itemBack.strBreadcrumbs = ( itemBack.r親ノード == null ) ?\r
942                                                 itemBack.strタイトル : itemBack.r親ノード.strBreadcrumbs + " > " + itemBack.strタイトル;\r
943 \r
944                                         itemBack.arスコア[ 0 ] = new Cスコア();\r
945                                         itemBack.arスコア[ 0 ].ファイル情報.フォルダの絶対パス = "";\r
946                                         itemBack.arスコア[ 0 ].譜面情報.タイトル = itemBack.strタイトル;\r
947                                         itemBack.arスコア[ 0 ].譜面情報.コメント =\r
948                                                 (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "ja") ?\r
949                                                 "BOX を出ます。" :\r
950                                                 "Exit from the BOX.";\r
951                                         c曲リストノード.list子リスト.Insert( 0, itemBack );\r
952 \r
953                                         #region [ ログ出力 ]\r
954                                         //-----------------------------\r
955                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
956                                         {\r
957                                                 StringBuilder sb = new StringBuilder( 0x100 );\r
958                                                 sb.Append( string.Format( "nID#{0:D3}", itemBack.nID ) );\r
959                                                 if( itemBack.r親ノード != null )\r
960                                                 {\r
961                                                         sb.Append( string.Format( "(in#{0:D3}):", itemBack.r親ノード.nID ) );\r
962                                                 }\r
963                                                 else\r
964                                                 {\r
965                                                         sb.Append( "(onRoot):" );\r
966                                                 }\r
967                                                 sb.Append( " BACKBOX" );\r
968                                                 Trace.TraceInformation( sb.ToString() );\r
969                                         }\r
970                                         //-----------------------------\r
971                                         #endregion\r
972 \r
973                                         this.t曲リストへ後処理を適用する( c曲リストノード.list子リスト );\r
974                                         continue;\r
975                                 }\r
976                                 //-----------------------------\r
977                                 #endregion\r
978 \r
979                                 #region [ ノードにタイトルがないなら、最初に見つけたスコアのタイトルを設定する ]\r
980                                 //-----------------------------\r
981                                 if( string.IsNullOrEmpty( c曲リストノード.strタイトル ) )\r
982                                 {\r
983                                         for( int j = 0; j < 5; j++ )\r
984                                         {\r
985                                                 if( ( c曲リストノード.arスコア[ j ] != null ) && !string.IsNullOrEmpty( c曲リストノード.arスコア[ j ].譜面情報.タイトル ) )\r
986                                                 {\r
987                                                         c曲リストノード.strタイトル = c曲リストノード.arスコア[ j ].譜面情報.タイトル;\r
988 \r
989                                                         if( CDTXMania.ConfigIni.bLog曲検索ログ出力 )\r
990                                                                 Trace.TraceInformation( "タイトルを設定しました。(nID#{0:D3}, title={1})", c曲リストノード.nID, c曲リストノード.strタイトル );\r
991 \r
992                                                         break;\r
993                                                 }\r
994                                         }\r
995                                 }\r
996                                 //-----------------------------\r
997                                 #endregion\r
998                         }\r
999 \r
1000                         #region [ ノードをソートする ]\r
1001                         //-----------------------------\r
1002                         this.t曲リストのソート1_絶対パス順( ノードリスト );\r
1003                         //-----------------------------\r
1004                         #endregion\r
1005                 }\r
1006                 //-----------------\r
1007                 #endregion\r
1008                 #region [ スコアキャッシュをSongsDBに出力する ]\r
1009                 //-----------------\r
1010                 public void tスコアキャッシュをSongsDBに出力する( string SongsDBファイル名 )\r
1011                 {\r
1012                         this.nSongsDBへ出力できたスコア数 = 0;\r
1013                         try\r
1014                         {\r
1015                                 BinaryWriter bw = new BinaryWriter( new FileStream( SongsDBファイル名, FileMode.Create, FileAccess.Write ) );\r
1016                                 bw.Write( SONGSDB_VERSION );\r
1017                                 this.tSongsDBにリストを1つ出力する( bw, this.list曲ルート );\r
1018                                 bw.Close();\r
1019                         }\r
1020                         catch\r
1021                         {\r
1022                                 Trace.TraceError( "songs.dbの出力に失敗しました。" );\r
1023                         }\r
1024                 }\r
1025                 private void tSongsDBにノードを1つ出力する( BinaryWriter bw, C曲リストノード node )\r
1026                 {\r
1027                         for( int i = 0; i < 5; i++ )\r
1028                         {\r
1029                                 // ここではsuspendに応じないようにしておく(深い意味はない。ファイルの書き込みオープン状態を長時間維持したくないだけ)\r
1030                                 //if ( this.bIsSuspending )             // #27060 中断要求があったら、解除要求が来るまで待機\r
1031                                 //{\r
1032                                 //      autoReset.WaitOne();\r
1033                                 //}\r
1034 \r
1035                                 if( node.arスコア[ i ] != null )\r
1036                                 {\r
1037                                         bw.Write( node.arスコア[ i ].ファイル情報.ファイルの絶対パス );\r
1038                                         bw.Write( node.arスコア[ i ].ファイル情報.フォルダの絶対パス );\r
1039                                         bw.Write( node.arスコア[ i ].ファイル情報.最終更新日時.Ticks );\r
1040                                         bw.Write( node.arスコア[ i ].ファイル情報.ファイルサイズ );\r
1041                                         bw.Write( node.arスコア[ i ].ScoreIni情報.最終更新日時.Ticks );\r
1042                                         bw.Write( node.arスコア[ i ].ScoreIni情報.ファイルサイズ );\r
1043                                         bw.Write( node.arスコア[ i ].譜面情報.タイトル );\r
1044                                         bw.Write( node.arスコア[ i ].譜面情報.アーティスト名 );\r
1045                                         bw.Write( node.arスコア[ i ].譜面情報.コメント );\r
1046                                         bw.Write( node.arスコア[ i ].譜面情報.ジャンル );\r
1047                                         bw.Write( node.arスコア[ i ].譜面情報.Preimage );\r
1048                                         bw.Write( node.arスコア[ i ].譜面情報.Premovie );\r
1049                                         bw.Write( node.arスコア[ i ].譜面情報.Presound );\r
1050                                         bw.Write( node.arスコア[ i ].譜面情報.Backgound );\r
1051                                         bw.Write( node.arスコア[ i ].譜面情報.レベル.Drums );\r
1052                                         bw.Write( node.arスコア[ i ].譜面情報.レベル.Guitar );\r
1053                                         bw.Write( node.arスコア[ i ].譜面情報.レベル.Bass );\r
1054                                         bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Drums );\r
1055                                         bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Guitar );\r
1056                                         bw.Write( node.arスコア[ i ].譜面情報.最大ランク.Bass );\r
1057                                         bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Drums );\r
1058                                         bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Guitar );\r
1059                                         bw.Write( node.arスコア[ i ].譜面情報.最大スキル.Bass );\r
1060                                         bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Drums );\r
1061                                         bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Guitar );\r
1062                                         bw.Write( node.arスコア[ i ].譜面情報.フルコンボ.Bass );\r
1063                                         bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Drums );\r
1064                                         bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Guitar );\r
1065                                         bw.Write( node.arスコア[ i ].譜面情報.演奏回数.Bass );\r
1066                                         bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行1 );\r
1067                                         bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行2 );\r
1068                                         bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行3 );\r
1069                                         bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行4 );\r
1070                                         bw.Write( node.arスコア[ i ].譜面情報.演奏履歴.行5 );\r
1071                                         bw.Write( node.arスコア[ i ].譜面情報.レベルを非表示にする );\r
1072                                         bw.Write( (int) node.arスコア[ i ].譜面情報.曲種別 );\r
1073                                         bw.Write( node.arスコア[ i ].譜面情報.Bpm );\r
1074                                         bw.Write( node.arスコア[ i ].譜面情報.Duration );\r
1075                                         this.nSongsDBへ出力できたスコア数++;\r
1076                                 }\r
1077                         }\r
1078                 }\r
1079                 private void tSongsDBにリストを1つ出力する( BinaryWriter bw, List<C曲リストノード> list )\r
1080                 {\r
1081                         foreach( C曲リストノード c曲リストノード in list )\r
1082                         {\r
1083                                 if(    ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE )\r
1084                                         || ( c曲リストノード.eノード種別 == C曲リストノード.Eノード種別.SCORE_MIDI ) )\r
1085                                 {\r
1086                                         this.tSongsDBにノードを1つ出力する( bw, c曲リストノード );\r
1087                                 }\r
1088                                 if( c曲リストノード.list子リスト != null )\r
1089                                 {\r
1090                                         this.tSongsDBにリストを1つ出力する( bw, c曲リストノード.list子リスト );\r
1091                                 }\r
1092                         }\r
1093                 }\r
1094                 //-----------------\r
1095                 #endregion\r
1096                 \r
1097                 #region [ 曲リストソート ]\r
1098                 //-----------------\r
1099                 public void t曲リストのソート1_絶対パス順( List<C曲リストノード> ノードリスト )\r
1100                 {\r
1101                         ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1102                         {\r
1103                                 #region [ 共通処理 ]\r
1104                                 if ( n1 == n2 )\r
1105                                 {\r
1106                                         return 0;\r
1107                                 }\r
1108                                 int num = this.t比較0_共通( n1, n2 );\r
1109                                 if( num != 0 )\r
1110                                 {\r
1111                                         return num;\r
1112                                 }\r
1113                                 if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1114                                 {\r
1115                                         return n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1116                                 }\r
1117                                 #endregion\r
1118                                 string str = "";\r
1119                                 if( string.IsNullOrEmpty( n1.pathSetDefの絶対パス ) )\r
1120                                 {\r
1121                                         for( int i = 0; i < 5; i++ )\r
1122                                         {\r
1123                                                 if( n1.arスコア[ i ] != null )\r
1124                                                 {\r
1125                                                         str = n1.arスコア[ i ].ファイル情報.ファイルの絶対パス;\r
1126                                                         if( str == null )\r
1127                                                         {\r
1128                                                                 str = "";\r
1129                                                         }\r
1130                                                         break;\r
1131                                                 }\r
1132                                         }\r
1133                                 }\r
1134                                 else\r
1135                                 {\r
1136                                         str = n1.pathSetDefの絶対パス + n1.SetDefのブロック番号.ToString( "00" );\r
1137                                 }\r
1138                                 string strB = "";\r
1139                                 if( string.IsNullOrEmpty( n2.pathSetDefの絶対パス ) )\r
1140                                 {\r
1141                                         for( int j = 0; j < 5; j++ )\r
1142                                         {\r
1143                                                 if( n2.arスコア[ j ] != null )\r
1144                                                 {\r
1145                                                         strB = n2.arスコア[ j ].ファイル情報.ファイルの絶対パス;\r
1146                                                         if( strB == null )\r
1147                                                         {\r
1148                                                                 strB = "";\r
1149                                                         }\r
1150                                                         break;\r
1151                                                 }\r
1152                                         }\r
1153                                 }\r
1154                                 else\r
1155                                 {\r
1156                                         strB = n2.pathSetDefの絶対パス + n2.SetDefのブロック番号.ToString( "00" );\r
1157                                 }\r
1158                                 return str.CompareTo( strB );\r
1159                         } );\r
1160                         foreach( C曲リストノード c曲リストノード in ノードリスト )\r
1161                         {\r
1162                                 if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
1163                                 {\r
1164                                         this.t曲リストのソート1_絶対パス順( c曲リストノード.list子リスト );\r
1165                                 }\r
1166                         }\r
1167                 }\r
1168                 public void t曲リストのソート2_タイトル順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1169                 {\r
1170                         ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1171                         {\r
1172                                 if( n1 == n2 )\r
1173                                 {\r
1174                                         return 0;\r
1175                                 }\r
1176                                 int num = this.t比較0_共通( n1, n2 );\r
1177                                 if( num != 0 )\r
1178                                 {\r
1179                                         return order * num;\r
1180                                 }\r
1181                                 return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1182                         } );\r
1183 //                      foreach( C曲リストノード c曲リストノード in ノードリスト )\r
1184 //                      {\r
1185 //                              if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
1186 //                              {\r
1187 //                                      this.t曲リストのソート2_タイトル順( c曲リストノード.list子リスト, part, order );\r
1188 //                              }\r
1189 //                      }\r
1190                 }\r
1191                 /// <summary>\r
1192                 /// \r
1193                 /// </summary>\r
1194                 /// <param name="ノードリスト"></param>\r
1195                 /// <param name="part"></param>\r
1196                 /// <param name="order">1=Ascend -1=Descend</param>\r
1197                 public void t曲リストのソート3_演奏回数の多い順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1198                 {\r
1199                         order = -order;\r
1200                         int nL12345 = (int) p[ 0 ];\r
1201                         if ( part != E楽器パート.UNKNOWN )\r
1202                         {\r
1203                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1204                                 {\r
1205                                         #region [ 共通処理 ]\r
1206                                         if ( n1 == n2 )\r
1207                                         {\r
1208                                                 return 0;\r
1209                                         }\r
1210                                         int num = this.t比較0_共通( n1, n2 );\r
1211                                         if( num != 0 )\r
1212                                         {\r
1213                                                 return order * num;\r
1214                                         }\r
1215                                         if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1216                                         {\r
1217                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1218                                         }\r
1219                                         #endregion\r
1220                                         int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
1221 //                                      for( int i = 0; i < 5; i++ )\r
1222 //                                      {\r
1223                                                 if( n1.arスコア[ nL12345 ] != null )\r
1224                                                 {\r
1225                                                         nSumPlayCountN1 += n1.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
1226                                                 }\r
1227                                                 if( n2.arスコア[ nL12345 ] != null )\r
1228                                                 {\r
1229                                                         nSumPlayCountN2 += n2.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
1230                                                 }\r
1231 //                                      }\r
1232                                         num = nSumPlayCountN2 - nSumPlayCountN1;\r
1233                                         if( num != 0 )\r
1234                                         {\r
1235                                                 return order * num;\r
1236                                         }\r
1237                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1238                                 } );\r
1239                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1240                                 {\r
1241                                         int nSumPlayCountN1 = 0;\r
1242 //                                      for ( int i = 0; i < 5; i++ )\r
1243 //                                      {\r
1244                                                 if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1245                                                 {\r
1246                                                         nSumPlayCountN1 += c曲リストノード.arスコア[ nL12345 ].譜面情報.演奏回数[ (int) part ];\r
1247                                                 }\r
1248 //                                      }\r
1249 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
1250                                 }\r
1251 \r
1252 //                              foreach( C曲リストノード c曲リストノード in ノードリスト )\r
1253 //                              {\r
1254 //                                      if( ( c曲リストノード.list子リスト != null ) && ( c曲リストノード.list子リスト.Count > 1 ) )\r
1255 //                                      {\r
1256 //                                              this.t曲リストのソート3_演奏回数の多い順( c曲リストノード.list子リスト, part );\r
1257 //                                      }\r
1258 //                              }\r
1259                         }\r
1260                 }\r
1261                 public void t曲リストのソート4_LEVEL順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1262                 {\r
1263                         order = -order;\r
1264                         int nL12345 = (int)p[ 0 ];\r
1265                         if ( part != E楽器パート.UNKNOWN )\r
1266                         {\r
1267                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1268                                 {\r
1269                                         #region [ 共通処理 ]\r
1270                                         if ( n1 == n2 )\r
1271                                         {\r
1272                                                 return 0;\r
1273                                         }\r
1274                                         int num = this.t比較0_共通( n1, n2 );\r
1275                                         if ( num != 0 )\r
1276                                         {\r
1277                                                 return order * num;\r
1278                                         }\r
1279                                         if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1280                                         {\r
1281                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1282                                         }\r
1283                                         #endregion\r
1284                                         int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
1285                                         if ( n1.arスコア[ nL12345 ] != null )\r
1286                                         {\r
1287                                                 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
1288                                         }\r
1289                                         if ( n2.arスコア[ nL12345 ] != null )\r
1290                                         {\r
1291                                                 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
1292                                         }\r
1293                                         num = nSumPlayCountN2 - nSumPlayCountN1;\r
1294                                         if ( num != 0 )\r
1295                                         {\r
1296                                                 return order * num;\r
1297                                         }\r
1298                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1299                                 } );\r
1300                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1301                                 {\r
1302                                         int nSumPlayCountN1 = 0;\r
1303                                         if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1304                                         {\r
1305                                                 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.レベル[ (int) part ];\r
1306                                         }\r
1307 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
1308                                 }\r
1309                         }\r
1310                 }\r
1311                 public void t曲リストのソート5_BestRank順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1312                 {\r
1313                         order = -order;\r
1314                         int nL12345 = (int) p[ 0 ];\r
1315                         if ( part != E楽器パート.UNKNOWN )\r
1316                         {\r
1317                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1318                                 {\r
1319                                         #region [ 共通処理 ]\r
1320                                         if ( n1 == n2 )\r
1321                                         {\r
1322                                                 return 0;\r
1323                                         }\r
1324                                         int num = this.t比較0_共通( n1, n2 );\r
1325                                         if ( num != 0 )\r
1326                                         {\r
1327                                                 return order * num;\r
1328                                         }\r
1329                                         if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1330                                         {\r
1331                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1332                                         }\r
1333                                         #endregion\r
1334                                         int nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
1335                                         bool isFullCombo1 = false, isFullCombo2 = false;\r
1336                                         if ( n1.arスコア[ nL12345 ] != null )\r
1337                                         {\r
1338                                                 isFullCombo1 = n1.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];\r
1339                                                 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
1340                                         }\r
1341                                         if ( n2.arスコア[ nL12345 ] != null )\r
1342                                         {\r
1343                                                 isFullCombo2 = n2.arスコア[ nL12345 ].譜面情報.フルコンボ[ (int) part ];\r
1344                                                 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
1345                                         }\r
1346                                         if ( isFullCombo1 ^ isFullCombo2 )\r
1347                                         {\r
1348                                                 if ( isFullCombo1 ) return order; else return -order;\r
1349                                         }\r
1350                                         num = nSumPlayCountN2 - nSumPlayCountN1;\r
1351                                         if ( num != 0 )\r
1352                                         {\r
1353                                                 return order * num;\r
1354                                         }\r
1355                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1356                                 } );\r
1357                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1358                                 {\r
1359                                         int nSumPlayCountN1 = 0;\r
1360                                         if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1361                                         {\r
1362                                                 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大ランク[ (int) part ];\r
1363                                         }\r
1364 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
1365                                 }\r
1366                         }\r
1367                 }\r
1368                 public void t曲リストのソート6_SkillPoint順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1369                 {\r
1370                         order = -order;\r
1371                         int nL12345 = (int) p[ 0 ];\r
1372                         if ( part != E楽器パート.UNKNOWN )\r
1373                         {\r
1374                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1375                                 {\r
1376                                         #region [ 共通処理 ]\r
1377                                         if ( n1 == n2 )\r
1378                                         {\r
1379                                                 return 0;\r
1380                                         }\r
1381                                         int num = this.t比較0_共通( n1, n2 );\r
1382                                         if ( num != 0 )\r
1383                                         {\r
1384                                                 return order * num;\r
1385                                         }\r
1386                                         if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1387                                         {\r
1388                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1389                                         }\r
1390                                         #endregion\r
1391                                         double nSumPlayCountN1 = 0, nSumPlayCountN2 = 0;\r
1392                                         if ( n1.arスコア[ nL12345 ] != null )\r
1393                                         {\r
1394                                                 nSumPlayCountN1 = n1.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
1395                                         }\r
1396                                         if ( n2.arスコア[ nL12345 ] != null )\r
1397                                         {\r
1398                                                 nSumPlayCountN2 = n2.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
1399                                         }\r
1400                                         double d = nSumPlayCountN2 - nSumPlayCountN1;\r
1401                                         if ( d != 0 )\r
1402                                         {\r
1403                                                 return order * System.Math.Sign(d);\r
1404                                         }\r
1405                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1406                                 } );\r
1407                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1408                                 {\r
1409                                         double nSumPlayCountN1 = 0;\r
1410                                         if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1411                                         {\r
1412                                                 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].譜面情報.最大スキル[ (int) part ];\r
1413                                         }\r
1414 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
1415                                 }\r
1416                         }\r
1417                 }\r
1418                 public void t曲リストのソート7_更新日時順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1419                 {\r
1420                         int nL12345 = (int) p[ 0 ];\r
1421                         if ( part != E楽器パート.UNKNOWN )\r
1422                         {\r
1423                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1424                                 {\r
1425                                         #region [ 共通処理 ]\r
1426                                         if ( n1 == n2 )\r
1427                                         {\r
1428                                                 return 0;\r
1429                                         }\r
1430                                         int num = this.t比較0_共通( n1, n2 );\r
1431                                         if ( num != 0 )\r
1432                                         {\r
1433                                                 return order * num;\r
1434                                         }\r
1435                                         if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1436                                         {\r
1437                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1438                                         }\r
1439                                         #endregion\r
1440                                         DateTime nSumPlayCountN1 = DateTime.Parse("0001/01/01 12:00:01.000");\r
1441                                         DateTime nSumPlayCountN2 = DateTime.Parse("0001/01/01 12:00:01.000");\r
1442                                         if ( n1.arスコア[ nL12345 ] != null )\r
1443                                         {\r
1444                                                 nSumPlayCountN1 = n1.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
1445                                         }\r
1446                                         if ( n2.arスコア[ nL12345 ] != null )\r
1447                                         {\r
1448                                                 nSumPlayCountN2 = n2.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
1449                                         }\r
1450                                         int d = nSumPlayCountN1.CompareTo(nSumPlayCountN2);\r
1451                                         if ( d != 0 )\r
1452                                         {\r
1453                                                 return order * System.Math.Sign( d );\r
1454                                         }\r
1455                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1456                                 } );\r
1457                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1458                                 {\r
1459                                         DateTime nSumPlayCountN1 = DateTime.Parse( "0001/01/01 12:00:01.000" );\r
1460                                         if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1461                                         {\r
1462                                                 nSumPlayCountN1 = c曲リストノード.arスコア[ nL12345 ].ファイル情報.最終更新日時;\r
1463                                         }\r
1464 // Debug.WriteLine( nSumPlayCountN1 + ":" + c曲リストノード.strタイトル );\r
1465                                 }\r
1466                         }\r
1467                 }\r
1468                 public void t曲リストのソート8_アーティスト名順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1469                 {\r
1470                         int nL12345 = (int) p[ 0 ]; \r
1471                         ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1472                         {\r
1473                                 if ( n1 == n2 )\r
1474                                 {\r
1475                                         return 0;\r
1476                                 }\r
1477                                 int num = this.t比較0_共通( n1, n2 );\r
1478                                 if ( num != 0 )\r
1479                                 {\r
1480                                         return order * System.Math.Sign( num );\r
1481                                 }\r
1482                                 string strAuthorN1 = "";\r
1483                                 string strAuthorN2 = "";\r
1484                                 if (n1.arスコア[ nL12345 ] != null ) {\r
1485                                         strAuthorN1 = n1.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
1486                                 }\r
1487                                 if ( n2.arスコア[ nL12345 ] != null )\r
1488                                 {\r
1489                                         strAuthorN2 = n2.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
1490                                 }\r
1491 \r
1492                                 return order * strAuthorN1.CompareTo( strAuthorN2 );\r
1493                         } );\r
1494                         foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1495                         {\r
1496                                 string s = "";\r
1497                                 if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1498                                 {\r
1499                                         s = c曲リストノード.arスコア[ nL12345 ].譜面情報.アーティスト名;\r
1500                                 }\r
1501 Debug.WriteLine( s + ":" + c曲リストノード.strタイトル );\r
1502                         }\r
1503                 }\r
1504 #if TEST_SORTBGM\r
1505                 public void t曲リストのソート9_BPM順( List<C曲リストノード> ノードリスト, E楽器パート part, int order, params object[] p )\r
1506                 {\r
1507                         order = -order;\r
1508                         int nL12345 = (int) p[ 0 ];\r
1509                         if ( part != E楽器パート.UNKNOWN )\r
1510                         {\r
1511                                 ノードリスト.Sort( delegate( C曲リストノード n1, C曲リストノード n2 )\r
1512                                 {\r
1513                                         #region [ 共通処理 ]\r
1514                                         if ( n1 == n2 )\r
1515                                         {\r
1516                                                 return 0;\r
1517                                         }\r
1518                                         int num = this.t比較0_共通( n1, n2 );\r
1519                                         if ( num != 0 )\r
1520                                         {\r
1521                                                 return order * num;\r
1522                                         }\r
1523                                         if ( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1524                                         {\r
1525                                                 return order * n1.arスコア[ 0 ].ファイル情報.フォルダの絶対パス.CompareTo( n2.arスコア[ 0 ].ファイル情報.フォルダの絶対パス );\r
1526                                         }\r
1527                                         #endregion\r
1528                                         double dBPMn1 = 0.0, dBPMn2 = 0.0;\r
1529                                         if ( n1.arスコア[ nL12345 ] != null )\r
1530                                         {\r
1531                                                 dBPMn1 = n1.arスコア[ nL12345 ].譜面情報.bpm;\r
1532                                         }\r
1533                                         if ( n2.arスコア[ nL12345 ] != null )\r
1534                                         {\r
1535                                                 dBPMn2 = n2.arスコア[ nL12345 ].譜面情報.bpm;\r
1536                                         }\r
1537                                         double d = dBPMn1- dBPMn2;\r
1538                                         if ( d != 0 )\r
1539                                         {\r
1540                                                 return order * System.Math.Sign( d );\r
1541                                         }\r
1542                                         return order * n1.strタイトル.CompareTo( n2.strタイトル );\r
1543                                 } );\r
1544                                 foreach ( C曲リストノード c曲リストノード in ノードリスト )\r
1545                                 {\r
1546                                         double dBPM = 0;\r
1547                                         if ( c曲リストノード.arスコア[ nL12345 ] != null )\r
1548                                         {\r
1549                                                 dBPM = c曲リストノード.arスコア[ nL12345 ].譜面情報.bpm;\r
1550                                         }\r
1551 Debug.WriteLine( dBPM + ":" + c曲リストノード.strタイトル );\r
1552                                 }\r
1553                         }\r
1554                 }\r
1555 #endif\r
1556                 //-----------------\r
1557                 #endregion\r
1558                 #region [ .score.ini を読み込んで Cスコア.譜面情報に設定する ]\r
1559                 //-----------------\r
1560                 public void tScoreIniを読み込んで譜面情報を設定する( string strScoreIniファイルパス, ref Cスコア score )\r
1561                 {\r
1562                         if( !File.Exists( strScoreIniファイルパス ) )\r
1563                                 return;\r
1564 \r
1565                         try\r
1566                         {\r
1567                                 var ini = new CScoreIni( strScoreIniファイルパス );\r
1568                                 ini.t全演奏記録セクションの整合性をチェックし不整合があればリセットする();\r
1569 \r
1570                                 for( int n楽器番号 = 0; n楽器番号 < 3; n楽器番号++ )\r
1571                                 {\r
1572                                         int n = ( n楽器番号 * 2 ) + 1;      // n = 0~5\r
1573 \r
1574                                         #region socre.譜面情報.最大ランク[ n楽器番号 ] = ... \r
1575                                         //-----------------\r
1576                                         if( ini.stセクション[ n ].b演奏にMIDI入力を使用した ||\r
1577                                                 ini.stセクション[ n ].b演奏にキーボードを使用した ||\r
1578                                                 ini.stセクション[ n ].b演奏にジョイパッドを使用した ||\r
1579                                                 ini.stセクション[ n ].b演奏にマウスを使用した )\r
1580                                         {\r
1581                                                 // (A) 全オートじゃないようなので、演奏結果情報を有効としてランクを算出する。\r
1582 \r
1583                                                 score.譜面情報.最大ランク[ n楽器番号 ] =\r
1584                                                         CScoreIni.tランク値を計算して返す( \r
1585                                                                 ini.stセクション[ n ].n全チップ数,\r
1586                                                                 ini.stセクション[ n ].nPerfect数, \r
1587                                                                 ini.stセクション[ n ].nGreat数,\r
1588                                                                 ini.stセクション[ n ].nGood数, \r
1589                                                                 ini.stセクション[ n ].nPoor数,\r
1590                                                                 ini.stセクション[ n ].nMiss数 );\r
1591                                         }\r
1592                                         else\r
1593                                         {\r
1594                                                 // (B) 全オートらしいので、ランクは無効とする。\r
1595 \r
1596                                                 score.譜面情報.最大ランク[ n楽器番号 ] = (int) CScoreIni.ERANK.UNKNOWN;\r
1597                                         }\r
1598                                         //-----------------\r
1599                                         #endregion\r
1600                                         score.譜面情報.最大スキル[ n楽器番号 ] = ini.stセクション[ n ].db演奏型スキル値;\r
1601                                         score.譜面情報.フルコンボ[ n楽器番号 ] = ini.stセクション[ n ].bフルコンボである;\r
1602                                 }\r
1603                                 score.譜面情報.演奏回数.Drums = ini.stファイル.PlayCountDrums;\r
1604                                 score.譜面情報.演奏回数.Guitar = ini.stファイル.PlayCountGuitar;\r
1605                                 score.譜面情報.演奏回数.Bass = ini.stファイル.PlayCountBass;\r
1606                                 for( int i = 0; i < 5; i++ )\r
1607                                         score.譜面情報.演奏履歴[ i ] = ini.stファイル.History[ i ];\r
1608                         }\r
1609                         catch\r
1610                         {\r
1611                                 Trace.TraceError( "演奏記録ファイルの読み込みに失敗しました。[{0}]", strScoreIniファイルパス );\r
1612                         }\r
1613                 }\r
1614                 //-----------------\r
1615                 #endregion\r
1616 \r
1617 \r
1618                 // その他\r
1619 \r
1620                 #region [ private ]\r
1621                 //-----------------\r
1622                 private const string SONGSDB_VERSION = "SongsDB3";\r
1623 \r
1624                 private int t比較0_共通( C曲リストノード n1, C曲リストノード n2 )\r
1625                 {\r
1626                         if( n1.eノード種別 == C曲リストノード.Eノード種別.BACKBOX )\r
1627                         {\r
1628                                 return -1;\r
1629                         }\r
1630                         if( n2.eノード種別 == C曲リストノード.Eノード種別.BACKBOX )\r
1631                         {\r
1632                                 return 1;\r
1633                         }\r
1634                         if( n1.eノード種別 == C曲リストノード.Eノード種別.RANDOM )\r
1635                         {\r
1636                                 return 1;\r
1637                         }\r
1638                         if( n2.eノード種別 == C曲リストノード.Eノード種別.RANDOM )\r
1639                         {\r
1640                                 return -1;\r
1641                         }\r
1642                         if( ( n1.eノード種別 == C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 != C曲リストノード.Eノード種別.BOX ) )\r
1643                         {\r
1644                                 return -1;\r
1645                         }\r
1646                         if( ( n1.eノード種別 != C曲リストノード.Eノード種別.BOX ) && ( n2.eノード種別 == C曲リストノード.Eノード種別.BOX ) )\r
1647                         {\r
1648                                 return 1;\r
1649                         }\r
1650                         return 0;\r
1651                 }\r
1652 \r
1653                 /// <summary>\r
1654                 /// 検索を中断・スローダウンする\r
1655                 /// </summary>\r
1656                 private void SlowOrSuspendSearchTask()\r
1657                 {\r
1658                         if ( this.bIsSuspending )               // #27060 中断要求があったら、解除要求が来るまで待機\r
1659                         {\r
1660                                 autoReset.WaitOne();\r
1661                         }\r
1662                         if ( this.bIsSlowdown && ++this.searchCount > 10 )                      // #27060 #PREMOVIE再生中は検索負荷を下げる\r
1663                         {\r
1664                                 Thread.Sleep( 100 );\r
1665                                 this.searchCount = 0;\r
1666                         }\r
1667                 }\r
1668 \r
1669                 //-----------------\r
1670                 #endregion\r
1671         }\r
1672 }\r