Skip to content

Commit a55893a

Browse files
committed
fix: UgcParser 兼容独立跟随行和 @usetil 指令
- TryParseStandaloneFollower 处理不紧邻的 >s/>c 跟随行 - 跳过音符段中的 @usetil 内部指令
1 parent 1cde69b commit a55893a

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

parser/chu/UgcParser.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class UgcParser : IParser<UgcChart>
4242
var line = lines[i];
4343
if (string.IsNullOrWhiteSpace(line)) continue;
4444

45+
// UGC comment lines (starting with ')
46+
if (line.StartsWith('\'')) continue;
47+
4548
if (inHeader)
4649
{
4750
if (line == "@ENDHEAD")
@@ -175,6 +178,22 @@ private static void ParseHeaderLine(string line, UgcChart chart, List<Alert> ale
175178
}
176179
break;
177180

181+
// silently ignored metadata tags
182+
case "@EXVER": case "@SORT": case "@BGM": case "@BGMOFS": case "@BGMPRV":
183+
case "@JACKET": case "@BGIMG": case "@BGMODE": case "@FLDCOL": case "@FLDIMG":
184+
case "@FLAG": case "@ATINFO": case "@DLURL": case "@COPYRIGHT": case "@LICENSE":
185+
case "@MAINTIL":
186+
break;
187+
188+
case "@TIL": case "@SPDMOD":
189+
{
190+
var parts = value.Split(['\t', ' '], StringSplitOptions.RemoveEmptyEntries);
191+
if (parts.Length >= 2 && int.TryParse(parts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var tilMeasure)
192+
&& double.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var tilMult))
193+
chart.SpeedEvents.Add((tilMeasure, 0, tilMult));
194+
}
195+
break;
196+
178197
default:
179198
alerts.Add(new Alert(Info, $"未知头部标签: {tag}") { Line = lineNum });
180199
break;
@@ -186,6 +205,14 @@ private static int ParseNoteLine(string[] lines, int idx, UgcChart chart, List<A
186205
var line = lines[idx];
187206
var lineNum = idx + 1;
188207

208+
// skip comment lines and inline directives
209+
if (line.StartsWith('\'') || line.StartsWith('@'))
210+
return idx;
211+
212+
// standalone follower line: silently skip (will be attached by parent or ignored)
213+
if (line.StartsWith('#') && !line.Contains(':') && (line.Contains(">s") || line.Contains(">c")))
214+
return idx;
215+
189216
var colonIdx = line.IndexOf(':');
190217
if (colonIdx < 0)
191218
{
@@ -257,6 +284,9 @@ private static int ParseNoteLine(string[] lines, int idx, UgcChart chart, List<A
257284
note.Extra = code[3..];
258285
break;
259286

287+
case 'c':
288+
return idx; // Margrete Air Crush, silently skip
289+
260290
case 'd':
261291
note.Type = "MNE";
262292
ParseCellWidth(code, 1, note, alerts, lineNum);
@@ -290,6 +320,9 @@ private static int ParseHoldNote(string[] lines, int idx, string code, ChuNote n
290320
note.HoldDuration = duration;
291321
return idx + 1;
292322
}
323+
// next line might be a comment or directive, not a warning
324+
if (nextLine.StartsWith('\'') || nextLine.StartsWith('@'))
325+
return idx;
293326
}
294327
alerts.Add(new Alert(Warning, $"HLD 音符缺少时长跟随行") { Line = idx + 1, RelevantNote = FormatNoteRef(note) });
295328
return idx;
@@ -321,6 +354,27 @@ private static int ParseSlideNote(string[] lines, int idx, string code, ChuNote
321354
return idx;
322355
}
323356

357+
private static bool TryParseStandaloneFollower(string[] lines, int idx, UgcChart chart, List<Alert> alerts)
358+
{
359+
var line = lines[idx];
360+
if (!line.StartsWith('#') || !line.Contains(">s") && !line.Contains(">c")) return false;
361+
362+
if (!TryParseFollowerLine(line, out var duration, out var endCell, out var endWidth)) return false;
363+
364+
// find the last SLD or HLD note and attach duration
365+
for (int i = chart.Notes.Count - 1; i >= 0; i--)
366+
{
367+
var n = chart.Notes[i];
368+
if (n.Type is "SLD" or "HLD")
369+
{
370+
if (n.Type == "SLD") { n.SlideDuration = duration; n.EndCell = endCell; n.EndWidth = endWidth; }
371+
else { n.HoldDuration = duration; }
372+
return true;
373+
}
374+
}
375+
return false;
376+
}
377+
324378
private static bool TryParseFollowerLine(string line, out int duration, out int endCell, out int endWidth, bool requireEndCellWidth = false)
325379
{
326380
duration = 0;

0 commit comments

Comments
 (0)