@@ -252,10 +252,14 @@ private static int ParseNoteLine(string[] lines, int idx, UgcChart chart, List<A
252252
253253 case 'f' :
254254 note . Type = "FLK" ;
255+ ParseCellWidth ( code , 1 , note , alerts , lineNum ) ;
256+ if ( code . Length > 3 )
257+ note . Extra = code [ 3 ..] ;
255258 break ;
256259
257260 case 'd' :
258261 note . Type = "MNE" ;
262+ ParseCellWidth ( code , 1 , note , alerts , lineNum ) ;
259263 break ;
260264
261265 default :
@@ -353,9 +357,18 @@ private static void ParseCellWidth(string code, int startIdx, ChuNote note, List
353357
354358 private static void ParseAirNote ( string code , ChuNote note , List < Alert > alerts , int lineNum )
355359 {
356- var remaining = code [ 1 ..] ;
357- var underscoreIdx = remaining . IndexOf ( '_' ) ;
358- var mainPart = underscoreIdx >= 0 ? remaining [ ..underscoreIdx ] : remaining ;
360+ // Matches UgcGenerator: "a" + cell + width + two-letter direction + targetNote [ + "_" + airHoldDuration for AHD ]
361+ if ( code . Length < 5 )
362+ {
363+ alerts . Add ( new Alert ( Warning , $ "AIR 音符代码过短: { code } ") { Line = lineNum } ) ;
364+ note . Type = "AIR" ;
365+ return ;
366+ }
367+
368+ ParseCellWidth ( code , 1 , note , alerts , lineNum ) ;
369+ var afterCellWidth = code [ 3 ..] ;
370+ var underscoreIdx = afterCellWidth . IndexOf ( '_' ) ;
371+ var mainPart = underscoreIdx >= 0 ? afterCellWidth [ ..underscoreIdx ] : afterCellWidth ;
359372
360373 if ( mainPart . Length < 2 )
361374 {
@@ -375,18 +388,11 @@ private static void ParseAirNote(string code, ChuNote note, List<Alert> alerts,
375388 alerts . Add ( new Alert ( Warning , $ "未知的 AIR 方向: { dir } ") { Line = lineNum , RelevantNote = FormatNoteRef ( note ) } ) ;
376389 }
377390
378- if ( mainPart . Length > 2 )
379- {
380- note . TargetNote = mainPart [ 2 ] . ToString ( ) ;
381- }
382- else
383- {
384- note . TargetNote = "N" ;
385- }
391+ note . TargetNote = mainPart . Length > 2 ? mainPart [ 2 ..] : "N" ;
386392
387393 if ( underscoreIdx >= 0 && note . Type == "AHD" )
388394 {
389- var durStr = remaining [ ( underscoreIdx + 1 ) ..] ;
395+ var durStr = afterCellWidth [ ( underscoreIdx + 1 ) ..] ;
390396 if ( int . TryParse ( durStr , NumberStyles . Integer , CultureInfo . InvariantCulture , out var ahdDuration ) )
391397 note . AirHoldDuration = ahdDuration ;
392398 }
@@ -395,11 +401,18 @@ private static void ParseAirNote(string code, ChuNote note, List<Alert> alerts,
395401 private static void ParseChrNote ( string code , ChuNote note , List < Alert > alerts , int lineNum )
396402 {
397403 note . Type = "CHR" ;
398- var extra = code [ 1 ..] ;
399- if ( ChrExtras . TryGetValue ( extra , out var chrDir ) )
404+ if ( code . Length < 3 )
405+ {
406+ alerts . Add ( new Alert ( Warning , $ "CHR 音符代码过短: { code } ") { Line = lineNum } ) ;
407+ return ;
408+ }
409+
410+ ParseCellWidth ( code , 1 , note , alerts , lineNum ) ;
411+ var extraRaw = code . Length > 3 ? code [ 3 ..] : "" ;
412+ if ( ChrExtras . TryGetValue ( extraRaw , out var chrDir ) )
400413 note . Extra = chrDir ;
401414 else
402- note . Extra = extra ;
415+ note . Extra = extraRaw ;
403416 }
404417
405418 private static int HexCharToInt ( char c )
0 commit comments